openapi: 3.1.0
info:
  title: DocuGraph REST & Sync API
  version: 1.0.0
  description: >
    API contract for DocuGraph backend service, providing user authentication,
    workspace indexing, DAG graph querying, MCP task context bundle extraction,
    automated traceability validation, and RevenueCat entitlement checking.

servers:
  - url: https://api.docugraph.io/api/v1
    description: Production Server
  - url: http://localhost:8080/api/v1
    description: Local Development Server

paths:
  /auth/login:
    post:
      summary: User Authentication & Token Generation
      description: Authenticates user credentials against PostgreSQL users table using Argon2id password hash, fetches subscription entitlement status, and returns RS256 signed JWT tokens.
      operationId: loginUser
      tags:
        - Authentication
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LoginRequest'
      responses:
        '200':
          description: Successfully authenticated. Returns access JWT and refresh token.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthTokenResponse'
        '401':
          description: Invalid email or password credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error for request body fields.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /projects:
    post:
      summary: Register & Scan Documentation Project Workspace
      description: Registers a new documentation project, verifies user subscription entitlement limits (max 3 active projects for Free tier), scans Markdown YAML frontmatter files using :docugraph-core, and persists graph nodes and edges.
      operationId: createProject
      tags:
        - Project Management
      security:
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateProjectRequest'
      responses:
        '201':
          description: Project created and workspace frontmatter index build initialized.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProjectResponse'
        '400':
          description: Invalid project request or workspace directory path does not exist.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized - Missing or invalid Bearer JWT token.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Forbidden - Free tier project limit (3 projects) exceeded. Upgrade to Pro tier required.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /projects/{id}/graph:
    get:
      summary: Retrieve Project Dependency Adjacency Graph
      description: Returns the full directed acyclic graph (DAG) structure containing all parsed atomic nodes and directed relationship edges for the specified project ID.
      operationId: buildGraph
      tags:
        - Graph Visualizer
      security:
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          description: UUID of the target project workspace
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Graph adjacency data successfully retrieved.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GraphDataResponse'
        '401':
          description: Unauthorized - Missing or invalid Bearer JWT token.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Project not found or access forbidden.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /mcp/task-context:
    post:
      summary: Extract MCP Task Context Bundle
      description: Performs reverse topological graph traversal starting from specified target taskId, gathers complete Markdown content for target node and upstream dependencies up to effective maxDepth, and returns formatted bundle. Enforces maxDepth=2 for Free tier subscribers.
      operationId: getTaskContext
      tags:
        - MCP Protocol Engine
      security:
        - McpApiKeyAuth: []
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TaskContextRequest'
      responses:
        '200':
          description: MCP task context bundle compiled successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TaskContextResponse'
        '401':
          description: Unauthorized - Invalid API key or Bearer token.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Task node ID not found in graph database.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /mcp/validate-traceability:
    post:
      summary: Validate Workspace Graph Integrity & Traceability
      description: Sweeps documentation workspace graph, executes Tarjan's SCC cycle detection algorithm, audits all file links and operationId references, and returns comprehensive health score report.
      operationId: validateTraceability
      tags:
        - MCP Protocol Engine
      security:
        - McpApiKeyAuth: []
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ValidateTraceabilityRequest'
      responses:
        '200':
          description: Traceability audit completed successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuditReportResponse'
        '401':
          description: Unauthorized - Invalid API key or Bearer token.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Target project or workspace directory not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /subscriptions/entitlement:
    get:
      summary: Verify User Subscription Entitlement Status
      description: Queries user entitlement tier against RevenueCat API v1 with cached offline grace limit support, returning active entitlement level (free or pro_tier) and feature limits.
      operationId: checkEntitlement
      tags:
        - Entitlements & Billing
      security:
        - BearerAuth: []
      responses:
        '200':
          description: Subscription entitlement status retrieved successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EntitlementStatusResponse'
        '401':
          description: Unauthorized - Missing or invalid Bearer JWT token.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: RS256 signed JSON Web Token issued upon successful login.
    McpApiKeyAuth:
      type: apiKey
      in: header
      name: X-MCP-API-KEY
      description: API Key header for authenticating MCP clients and AI agents.

  schemas:
    LoginRequest:
      type: object
      required:
        - email
        - password
      properties:
        email:
          type: string
          format: email
          example: developer@docugraph.io
        password:
          type: string
          format: password
          minLength: 8
          example: SecureP@ssw0rd!

    AuthTokenResponse:
      type: object
      required:
        - access_token
        - refresh_token
        - token_type
        - expires_in
        - entitlement_id
        - user
      properties:
        access_token:
          type: string
          example: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
        refresh_token:
          type: string
          example: d9f8e7c6b5a4...
        token_type:
          type: string
          example: Bearer
        expires_in:
          type: integer
          example: 900
        entitlement_id:
          type: string
          enum: [free, pro_tier]
          example: pro_tier
        user:
          $ref: '#/components/schemas/UserProfile'

    UserProfile:
      type: object
      required:
        - id
        - email
      properties:
        id:
          type: string
          format: uuid
          example: 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d
        email:
          type: string
          format: email
          example: developer@docugraph.io
        full_name:
          type: string
          nullable: true
          example: Lead Developer

    CreateProjectRequest:
      type: object
      required:
        - name
        - workspace_path
      properties:
        name:
          type: string
          maxLength: 100
          example: DocuGraph Core Engine
        description:
          type: string
          nullable: true
          example: Multiplatform documentation graph engine monorepo
        workspace_path:
          type: string
          example: /home/user/projects/docugraph
        git_remote_url:
          type: string
          nullable: true
          example: https://github.com/docugraph/docugraph.git
        git_default_branch:
          type: string
          default: main
          example: main
        schema_config:
          type: object
          default: {}

    ProjectResponse:
      type: object
      required:
        - id
        - owner_id
        - name
        - workspace_path
        - status
        - node_count
        - edge_count
        - created_at
        - updated_at
      properties:
        id:
          type: string
          format: uuid
          example: 123e4567-e89b-12d3-a456-426614174000
        owner_id:
          type: string
          format: uuid
          example: 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d
        name:
          type: string
          example: DocuGraph Core Engine
        description:
          type: string
          nullable: true
          example: Multiplatform documentation graph engine monorepo
        workspace_path:
          type: string
          example: /home/user/projects/docugraph
        git_remote_url:
          type: string
          nullable: true
          example: https://github.com/docugraph/docugraph.git
        status:
          type: string
          enum: [INITIALIZING, ACTIVE, INDEXING_FAILED, ARCHIVED]
          example: ACTIVE
        node_count:
          type: integer
          example: 42
        edge_count:
          type: integer
          example: 78
        last_indexed_at:
          type: string
          format: date-time
          nullable: true
          example: '2026-08-04T10:00:00Z'
        created_at:
          type: string
          format: date-time
          example: '2026-08-04T09:30:00Z'
        updated_at:
          type: string
          format: date-time
          example: '2026-08-04T10:00:00Z'

    GraphDataResponse:
      type: object
      required:
        - project_id
        - nodes
        - edges
        - total_nodes
        - total_edges
      properties:
        project_id:
          type: string
          format: uuid
          example: 123e4567-e89b-12d3-a456-426614174000
        nodes:
          type: array
          items:
            $ref: '#/components/schemas/GraphNode'
        edges:
          type: array
          items:
            $ref: '#/components/schemas/GraphEdge'
        total_nodes:
          type: integer
          example: 42
        total_edges:
          type: integer
          example: 78

    GraphNode:
      type: object
      required:
        - id
        - atomic_id
        - title
        - document_type
        - status
        - relative_file_path
        - file_checksum_sha256
      properties:
        id:
          type: string
          format: uuid
          example: a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d
        atomic_id:
          type: string
          example: US-01
        title:
          type: string
          example: User Authentication & Login Flow
        document_type:
          type: string
          example: user_story
        status:
          type: string
          enum: [DRAFT, IN_REVIEW, APPROVED, DEPRECATED]
          example: APPROVED
        relative_file_path:
          type: string
          example: docs/user_stories/US-01_login.md
        file_checksum_sha256:
          type: string
          example: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
        frontmatter_json:
          type: object
          default: {}
        tags:
          type: array
          items:
            type: string
          example: [auth, login, security]

    GraphEdge:
      type: object
      required:
        - id
        - source_node_id
        - target_node_id
        - relationship_type
      properties:
        id:
          type: string
          format: uuid
          example: f1e2d3c4-b5a6-9788-7654-3210fedcba98
        source_node_id:
          type: string
          format: uuid
          example: a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d
        target_node_id:
          type: string
          format: uuid
          example: c9b8a7f6-e5d4-3c2b-1a0f-9e8d7c6b5a4f
        relationship_type:
          type: string
          enum: [depends_on, depended_by, related, tables]
          example: depends_on

    TaskContextRequest:
      type: object
      required:
        - taskId
      properties:
        taskId:
          type: string
          example: US-01
        maxDepth:
          type: integer
          default: 5
          example: 3
        includeSourceCode:
          type: boolean
          default: true
          example: true

    TaskContextResponse:
      type: object
      required:
        - taskId
        - requestedMaxDepth
        - effectiveMaxDepth
        - truncated
        - markdownBundle
        - collectedNodes
      properties:
        taskId:
          type: string
          example: US-01
        requestedMaxDepth:
          type: integer
          example: 5
        effectiveMaxDepth:
          type: integer
          example: 2
        truncated:
          type: boolean
          example: true
        markdownBundle:
          type: string
          example: "# TASK CONTEXT BUNDLE: US-01\n..."
        collectedNodes:
          type: array
          items:
            type: string
          example: [US-01, VISION-00, SCHEMA-01]

    ValidateTraceabilityRequest:
      type: object
      properties:
        project_id:
          type: string
          format: uuid
          nullable: true
          example: 123e4567-e89b-12d3-a456-426614174000
        workspace_path:
          type: string
          nullable: true
          example: /home/user/projects/docugraph

    AuditReportResponse:
      type: object
      required:
        - health_score
        - total_nodes
        - total_edges
        - broken_links_count
        - circular_dependencies_count
        - broken_links
        - circular_dependencies
        - missing_operation_ids
      properties:
        health_score:
          type: number
          format: float
          example: 98.5
        total_nodes:
          type: integer
          example: 42
        total_edges:
          type: integer
          example: 78
        broken_links_count:
          type: integer
          example: 1
        circular_dependencies_count:
          type: integer
          example: 0
        broken_links:
          type: array
          items:
            $ref: '#/components/schemas/BrokenLinkItem'
        circular_dependencies:
          type: array
          items:
            $ref: '#/components/schemas/CircularDependencyItem'
        missing_operation_ids:
          type: array
          items:
            type: string

    BrokenLinkItem:
      type: object
      required:
        - source_node
        - target_ref
        - error_message
      properties:
        source_node:
          type: string
          example: FE-01
        target_ref:
          type: string
          example: BE-99
        error_message:
          type: string
          example: Referenced target node BE-99 does not exist in graph index.

    CircularDependencyItem:
      type: object
      required:
        - cycle_path
      properties:
        cycle_path:
          type: array
          items:
            type: string
          example: [BE-01, BE-02, BE-01]

    EntitlementStatusResponse:
      type: object
      required:
        - entitlement_id
        - status
        - is_pro
        - max_projects_allowed
        - max_traversal_depth
      properties:
        entitlement_id:
          type: string
          enum: [free, pro_tier]
          example: pro_tier
        status:
          type: string
          enum: [active, canceled, grace_period, expired]
          example: active
        is_pro:
          type: boolean
          example: true
        revenuecat_customer_id:
          type: string
          nullable: true
          example: app_user_9b1deb4d
        expires_at:
          type: string
          format: date-time
          nullable: true
          example: '2027-08-04T10:00:00Z'
        offline_grace_until:
          type: string
          format: date-time
          nullable: true
          example: '2026-08-11T10:00:00Z'
        max_projects_allowed:
          type: integer
          example: -1
        max_traversal_depth:
          type: integer
          example: -1

    ErrorResponse:
      type: object
      required:
        - code
        - message
        - timestamp
      properties:
        code:
          type: string
          example: INVALID_CREDENTIALS
        message:
          type: string
          example: The provided email or password is incorrect.
        timestamp:
          type: string
          format: date-time
          example: '2026-08-04T10:14:00Z'
        details:
          type: object
          nullable: true
