File size: 2,226 Bytes
71b4454
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
from __future__ import annotations

import asyncio
import logging
from datetime import datetime, timezone
from pathlib import Path
from typing import Any

logger = logging.getLogger("deployment_engine")

ROOT = Path(__file__).resolve().parents[2]
PROJECTS = ROOT / "generated_projects"
DEPLOYMENTS = ROOT / "deployments"


class DeploymentEngine:
    async def deploy_project(
        self,
        project_id: str,
        environment: str = "staging",
    ) -> dict[str, Any]:
        if not project_id or not project_id.strip():
            raise ValueError("project_id is required")

        environment = environment.strip().lower()

        if environment not in {"development", "staging", "production"}:
            raise ValueError(
                "environment must be development, staging, or production"
            )

        project_dir = PROJECTS / project_id

        if not project_dir.exists():
            raise FileNotFoundError(
                f"Project workspace not found: {project_id}"
            )

        if not project_dir.is_dir():
            raise NotADirectoryError(
                f"Project workspace is not a directory: {project_id}"
            )

        DEPLOYMENTS.mkdir(parents=True, exist_ok=True)

        stamp = datetime.now(timezone.utc).isoformat()

        record = {
            "status": "success",
            "project_id": project_id,
            "environment": environment,
            "project_path": str(project_dir),
            "deployed_at": stamp,
            "deployment_id": (
                f"deploy_{project_id}_"
                f"{int(datetime.now(timezone.utc).timestamp())}"
            ),
        }

        await asyncio.to_thread(
            self._write_record,
            record,
        )

        logger.info(
            "Deployment completed: project=%s environment=%s",
            project_id,
            environment,
        )

        return record

    def _write_record(self, record: dict[str, Any]) -> None:
        path = DEPLOYMENTS / f"{record['deployment_id']}.json"

        import json

        path.write_text(
            json.dumps(record, indent=2),
            encoding="utf-8",
        )


deployment_engine = DeploymentEngine()