docs: Epic-001 v1.2 — Implementation plan + Development rules

- Added Vision: 'LandveX Intelligence Lab is the internal factory where
  raw reality is refined into verified Control Intelligence'
- Added Architecture Goal: Every artifact traceable backward to source
  and forward to decision
- Added Development Rule: No Story starts with UI. Order: Domain model →
  API → Storage → Tests → UI
- Added Story 1 implementation plan with 5 PRs:
  PR-001: Domain Model (Mission, MissionAsset, Upload, types)
  PR-002: Storage (S3/R2 bucket, PostgreSQL metadata, checksums, EXIF, GPS)
  PR-003: API (POST /missions, POST /missions/{id}/assets, GET /missions)
  PR-004: Events (MissionCreated, AssetUploaded, RawDatasetReady)
  PR-005: UI (simple drag-and-drop upload with progress)
- Added Definition of Done for Story 1:
  Phone → Video → Upload → Bucket → Metadata → Mission visible in Dataset Explorer
- Added ID Convention: mission_YYYYMMDD_NNNNNN, asset_NNNNNN, obs_NNNNNN,
  decision_NNNNNN. Never UUID in UI.
- Added Artifact Viewer: show raw asset metadata, hash, GPS, EXIF,
  storage location, version for debugging

Rationale: Clean architecture, testable without UI, traceable artifacts.
This commit is contained in:
Bernt
2026-07-02 13:41:16 +00:00
parent 9e4ebeea1a
commit 37ef2f4526
+156 -2
View File
@@ -371,6 +371,160 @@ These are important but don't help reach the first verified workflow.
---
## STATUS
## Vision
**READY FOR DEVELOPMENT**
**LandveX Intelligence Lab is the internal factory where raw reality is refined into verified Control Intelligence.**
**Architecture Goal:** Every artifact must be traceable backward to its source and forward to its decision.
## Development Rule
**No Story may start with UI. Every Story starts with:**
1. Domain model
2. API
3. Storage
4. Tests
5. UI
This keeps architecture clean and allows testing each part without frontend.
## Story 1: Mission Import — Implementation Plan
### PR-001: Domain Model
```typescript
// Mission
interface Mission {
id: string; // mission_20260814_000123
status: MissionStatus;
location: Location;
device: Device;
createdAt: Date;
updatedAt: Date;
}
// MissionAsset
interface MissionAsset {
id: string; // asset_000456
missionId: string;
type: AssetType; // image | video
storagePath: string;
checksum: string;
sizeBytes: number;
mimeType: string;
metadata: AssetMetadata;
createdAt: Date;
}
// AssetMetadata
interface AssetMetadata {
exif: ExifData;
gps: GpsCoordinates;
device: DeviceInfo;
}
// Upload
interface Upload {
id: string;
missionId: string;
status: UploadStatus;
progress: number;
startedAt: Date;
completedAt?: Date;
}
// Enums
type MissionStatus = 'created' | 'uploading' | 'processing' | 'completed' | 'failed';
type AssetType = 'image' | 'video';
type UploadStatus = 'pending' | 'in_progress' | 'completed' | 'failed';
```
### PR-002: Storage
- Upload to bucket (S3/R2)
- Metadata in PostgreSQL
- Checksums (SHA-256)
- File size
- MIME type
- EXIF extraction
- GPS parsing
- **No AI yet**
### PR-003: API
```
POST /missions
POST /missions/{id}/assets
GET /missions/{id}
GET /missions
```
### PR-004: Events
```
MissionCreated
AssetUploaded
RawDatasetReady
```
**No pipeline yet. Just events.**
### PR-005: UI
Extremely simple:
```
Mission Import
[Drag files] or [Choose files]
[Upload]
Progress: ████████░░ 80%
Done! Mission mission_20260814_000123 created.
```
### Definition of Done (Story 1)
```
Phone → Video → Upload → Bucket → Metadata → Mission visible in Dataset Explorer
```
This is the first proof.
## ID Convention
**Never UUID in UI. UUID internally.**
| Entity | ID Format | Example |
|--------|-----------|---------|
| Mission | `mission_YYYYMMDD_NNNNNN` | `mission_20260814_000123` |
| Asset | `asset_NNNNNN` | `asset_000456` |
| Observation | `obs_NNNNNN` | `obs_000981` |
| Decision | `decision_NNNNNN` | `decision_000044` |
## Artifact Viewer
When clicking a file, show:
```
Raw Asset
├── Filename: IMG_20260814_143052.jpg
├── Size: 4.2 MB
├── MIME: image/jpeg
├── Hash: sha256:a3f7...
├── GPS: 59.2371, 18.1456
├── EXIF: Device=iPhone14,2, ISO=100, Exposure=1/120s
├── Created: 2026-08-14 14:30:52 UTC
├── Storage: s3://landvex-raw/2026/08/14/mission_20260814_000123/
└── Version: 1
```
Saves enormous time during debugging.
## Status
**READY FOR DEVELOPMENT — PR-001: Domain Model**