Document the already-decided decomposition of subplan-02 Slice 1 so the P2.1 boundary is verifiable from the repo: - P2.1 = Core Structs + boundary validation (validation portion of Slice 1) - P2.3 = in-memory repository + db.json (rest of Slice 1) - Token = Slice 5 (Token Security), out of both Planning-doc record only; no domain or test code changed.
157 lines
2.8 KiB
Markdown
157 lines
2.8 KiB
Markdown
# Subplan 02 - Product Domain And Storage
|
|
|
|
> **Flow decomposition:** Slice 1 is split across two flow steps — **P2.1**
|
|
> (Core Structs + boundary validation) and **P2.3** (in-memory repository +
|
|
> `db.json` persistence). Token ships in **Slice 5 - Token Security**, not
|
|
> Slice 1. See "Milestone 1 — Flow Step ↔ Subplan Slice Mapping" in `PLAN.md`.
|
|
|
|
## Goal
|
|
|
|
Define the distribution platform's core data model and persistence layer once
|
|
the required std primitives exist.
|
|
|
|
## Core Structs
|
|
|
|
App:
|
|
|
|
- id
|
|
- slug
|
|
- display_name
|
|
- bundle identifiers by platform
|
|
- owner
|
|
- visibility
|
|
- created_at
|
|
- updated_at
|
|
|
|
Platform:
|
|
|
|
- ios
|
|
- android_apk
|
|
- macos
|
|
- linux
|
|
- windows
|
|
|
|
Artifact:
|
|
|
|
- id
|
|
- app_id
|
|
- release_id
|
|
- platform
|
|
- filename
|
|
- content_type
|
|
- size_bytes
|
|
- sha256
|
|
- storage_key
|
|
- metadata
|
|
- validation_status
|
|
|
|
Release:
|
|
|
|
- id
|
|
- app_id
|
|
- version
|
|
- build
|
|
- channel
|
|
- notes
|
|
- created_by
|
|
- created_at
|
|
- published_at
|
|
|
|
Channel:
|
|
|
|
- app_id
|
|
- name
|
|
- current_release_id
|
|
- policy
|
|
- rollout_percent
|
|
|
|
Token:
|
|
|
|
- id
|
|
- name
|
|
- token_hash
|
|
- scopes
|
|
- created_at
|
|
- expires_at
|
|
- last_used_at
|
|
- revoked_at
|
|
|
|
AuditEvent:
|
|
|
|
- id
|
|
- actor
|
|
- action
|
|
- target_type
|
|
- target_id
|
|
- metadata
|
|
- created_at
|
|
|
|
## Slice 1 - In-Memory Model
|
|
|
|
Deliver:
|
|
|
|
- In-memory repository interfaces.
|
|
- Basic create/list/get/update operations.
|
|
- Domain validation for slugs, versions, channels, and platform ids.
|
|
|
|
Acceptance:
|
|
|
|
- CLI and HTTP tests can run without SQLite.
|
|
- Invalid app/release/artifact state is rejected at the domain boundary.
|
|
|
|
## Slice 2 - SQLite Schema
|
|
|
|
Deliver:
|
|
|
|
- Schema migrations.
|
|
- Tables for apps, releases, artifacts, channels, tokens, audit events.
|
|
- Indexes for slug lookup, app releases, artifact digest lookup, token hash.
|
|
- Transaction wrapper for publish flows.
|
|
|
|
Acceptance:
|
|
|
|
- A release and all artifacts can be created atomically.
|
|
- Channel promotion can be rolled back if a validation gate fails.
|
|
|
|
## Slice 3 - Artifact Storage
|
|
|
|
Deliver:
|
|
|
|
- Content-addressed storage by SHA-256.
|
|
- Staging directory for uploads.
|
|
- Atomic move from staging to final storage.
|
|
- Metadata sidecar or DB rows for content type, size, and platform metadata.
|
|
|
|
Acceptance:
|
|
|
|
- Duplicate artifact bytes are not stored twice unless policy requires it.
|
|
- Interrupted uploads do not create published artifacts.
|
|
|
|
## Slice 4 - Retention And Cleanup
|
|
|
|
Deliver:
|
|
|
|
- Retention policy per app/channel.
|
|
- Cleanup of unreferenced staged files.
|
|
- Audit events for deletion.
|
|
|
|
Acceptance:
|
|
|
|
- Stable releases can be retained longer than beta/internal builds.
|
|
- Cleanup never deletes the release currently pointed at by a channel.
|
|
|
|
## Slice 5 - Token Security
|
|
|
|
Deliver:
|
|
|
|
- Token generation.
|
|
- Token hashing at rest.
|
|
- Scope checks.
|
|
- Expiration and revocation.
|
|
- Last-used audit updates.
|
|
|
|
Acceptance:
|
|
|
|
- Raw tokens are shown only once.
|
|
- CI publish tokens can be scoped to one app and one channel.
|