# 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.
