Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Used by AI AGENTS to skip analyzing these files
.history
.tmp
_.bak
node_modules/
/coverage/
/dist/
/env/
_.DS*Store
.vscode/values-schema.yaml
*.env
/.secrets
chart/apl/values.schema.json
chart/apl/README.md
workflow/
\_.new
.envrc
otomi.cpuprofile
/.idea/
tmp
\*\*values-repo.yaml
26 changes: 26 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
## OVERVIEW

App Platform API — Express/TypeScript REST API managing Kubernetes teams, workloads, and services. Uses **Git as database** (YAML files in a values repo).

## CONVENTIONS

- **OpenAPI-first**: Never add routes manually. Define in YAML spec, implement handler matching `operationId`
- **Handler signature (all versions)**: `export const opId = (req: OpenApiRequestExt, res: Response): void` — send via `res.json()`
- **Path params use curly braces in filesystem**: `src/api/v1/teams/{teamId}/services.ts` — Express resolves `:teamId`

## Deprecations

- /v1 is deprecated, new endpoints implemented in /v2
- src/ai not used

## KEY PATTERNS

- **Git-as-Database**: CRUD → OtomiStack → FileStore (memory) + Git (disk) → commit → deploy
- **Multi-tenant isolation**: Team resources scoped by `teamId` in paths and CASL abilities
- **OpenAPI validation**: express-openapi-validator validates all requests/responses against specs
- **FileStore path mapping**: FileMap defines glob patterns + templates per AplKind (e.g., `env/teams/{teamId}/services/{name}.yaml`)

## ANTI-PATTERNS

- **DO NOT** edit `src/generated-schema.ts` — auto-generated from `npm run build:models`
- **DO NOT** add routes without OpenAPI spec — express-openapi-validator rejects unspecified routes
27 changes: 27 additions & 0 deletions src/api/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# API Route Handlers

## OVERVIEW

Versioned REST endpoint handlers. Each file exports functions matching OpenAPI `operationId`s.

## STRUCTURE

```
api/
├── v1/ # Legacy handlers — (req, res) signature, call req.otomi.*
├── v2/ # Current handlers — (req, res) signature, call req.otomi.*Apl*
│ └── teams/{teamId}/ # Team-scoped with sub-resource dirs
├── alpha/ # Experimental (AI features, team extensions)
│ ├── ai/ # Deprecated
│ └── teams/ # Deprecated
└── apiDocs.ts # Swagger UI endpoint
```

## CONVENTIONS

- **v2 handlers**: `export const opId = (req: OpenApiRequestExt, res: Response): void` — call `req.otomi.*Apl*()`, send via `res.json()`

## ANTI-PATTERNS

- **DO NOT** put business logic in handlers — delegate to `req.otomi` (OtomiStack)
- **DO NOT** create handler files without corresponding OpenAPI spec entry
22 changes: 22 additions & 0 deletions src/openapi/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# OpenAPI Specifications

## OVERVIEW

YAML specs defining all API endpoints, schemas, ACLs, and documentation links. Single source of truth for the entire API surface.

## CONVENTIONS

- **`operationId`**: Must match exported function name in handler file
- **`x-eov-operation-handler`**: Path to handler file relative to `src/api/` (e.g., `v1/teams`)
- **`x-aclSchema`**: References schema name for CASL authorization
- **`x-acl`**: Maps roles to CRUD abilities (`create-any`, `read`, `update`, `delete-any`)
- **`x-formtype`**: UI hint for console form generation (`SelectWidget`, etc.)
- **`x-externalDocsPath`**: Appended to base docs URL for per-resource documentation
- **Schema files** define the resource type at top level (e.g., `Service:` in `service.yaml`)

## ANTI-PATTERNS

- **DO NOT** add paths without `operationId` and `x-eov-operation-handler`
- **DO NOT** define schemas inline in `api.yaml` — create separate `{resource}.yaml`
- **DO NOT** forget `x-aclSchema` — endpoints without it bypass authorization
- After changes: run `npm run build:models` to regenerate `generated-schema.ts`
Loading