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:
@@ -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**
|
||||||
|
|||||||
Reference in New Issue
Block a user