- SvelteKit 2 (Svelte 5) with TypeScript, static adapter (SPA mode) - Capacitor config for iOS/Android (so.toph.solidhaus) - Tailwind CSS v4 via Vite plugin - All dependencies: idb, nanoid, bwip-js, jspdf, Automerge, Solid - Route stubs: dashboard, scan, items, locations, labels, settings - Type definitions and ID generator utility - Project specification and ontology files Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
616 lines
22 KiB
Markdown
616 lines
22 KiB
Markdown
# SolidHaus — Household Inventory Management on Solid + RDF
|
|
|
|
**Project Codename:** SolidHaus
|
|
**Author:** Christopher (toph)
|
|
**Date:** 2026-02-26
|
|
**Status:** Design / Brainstorm Phase
|
|
**Version:** 2.0
|
|
|
|
---
|
|
|
|
## 1. Vision & Goals
|
|
|
|
SolidHaus is a **local-first, multi-user, Solid-compatible household inventory management system** that lets you track every physical item in your home using semantic web technologies (RDF, schema.org, Linked Data). Items are identified by short 7-character auto-generated IDs (nanoid), which are pre-printed as QR codes on label sheets. The app scans these codes to log sightings, locations, and usage — building a living knowledge graph of your possessions.
|
|
|
|
### Core Principles
|
|
|
|
- **Data Sovereignty**: All data lives in your Solid Pod (Community Solid Server / CSS). You own it.
|
|
- **Local-First + Multi-User**: Works offline, syncs between household members via CRDT (Automerge). No cloud dependency for core operations.
|
|
- **Semantic Web Native**: Uses schema.org vocabulary + custom ontology extensions. Data is RDF (JSON-LD / Turtle).
|
|
- **Scan-First UX**: Optimized for walking around with a phone, scanning barcodes, and quickly updating item locations.
|
|
- **Pre-Printed Labels**: Batch-generate QR code sheets with pre-allocated IDs. Peel, stick, scan to associate.
|
|
- **Check-In / Check-Out**: Items have a custody state — tracked from storage to active use and back.
|
|
- **From Tools to Pantry**: Supports durable goods, consumables, and perishables with quantity tracking.
|
|
|
|
---
|
|
|
|
## 2. Architecture Overview
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────┐
|
|
│ SolidHaus App │
|
|
│ (SvelteKit + Capacitor, native on Android/iOS) │
|
|
│ │
|
|
│ ┌──────────┐ ┌──────────┐ ┌───────────────────┐ │
|
|
│ │ Scanner │ │ Inventory│ │ Label Sheet │ │
|
|
│ │ (Camera) │ │ Browser │ │ Generator (PDF) │ │
|
|
│ └────┬─────┘ └────┬─────┘ └────────┬──────────┘ │
|
|
│ │ │ │ │
|
|
│ ┌────▼──────────────▼──────────────────▼──────────┐ │
|
|
│ │ Local Data Layer │ │
|
|
│ │ (IndexedDB + Automerge CRDT) │ │
|
|
│ └────────────────────┬────────────────────────────┘ │
|
|
│ │ │
|
|
│ ┌────────────────────▼────────────────────────────┐ │
|
|
│ │ Sync Layer │ │
|
|
│ │ Automerge-repo (WebSocket) + Solid RDF export │ │
|
|
│ └────────────────────┬────────────────────────────┘ │
|
|
└───────────────────────┼──────────────────────────────┘
|
|
│
|
|
┌─────────────┼──────────────┐
|
|
▼ ▼
|
|
┌─────────────────┐ ┌──────────────────┐
|
|
│ Automerge Sync │ │ Solid Pod │
|
|
│ Server (NixOS) │ │ (CSS / NSS) │
|
|
│ (WebSocket) │ │ /inventory/ │
|
|
└─────────────────┘ └──────────────────┘
|
|
```
|
|
|
|
### Technology Stack
|
|
|
|
| Layer | Technology | Rationale |
|
|
|-------|-----------|-----------|
|
|
| **Framework** | SvelteKit 2 (Svelte 5 with runes) | Compiler-first, minimal overhead, excellent DX |
|
|
| **Native Wrapper** | Capacitor | Android/iOS from single codebase, native API access |
|
|
| **Build** | Vite (built into SvelteKit) | Fast, modern bundler |
|
|
| **Local Storage** | IndexedDB (via idb) | Reliable offline storage for structured data |
|
|
| **CRDT / Sync** | Automerge + automerge-repo | Conflict-free multi-user sync between household members |
|
|
| **RDF/Solid** | @inrupt/solid-client, @inrupt/solid-client-authn-browser | Solid Pod interaction, RDF serialization |
|
|
| **Barcode Scanning (native)** | @capacitor-mlkit/barcode-scanning | ML Kit — fast, supports all formats on Android/iOS |
|
|
| **Barcode Scanning (web)** | Barcode Detection API + ZXing fallback | Native browser API on Chrome, polyfill for others |
|
|
| **Barcode Rendering** | bwip-js | Generate barcode/QR images for label sheets |
|
|
| **ID Generation** | nanoid (custom alphabet) | Short, URL-safe, collision-resistant IDs |
|
|
| **Styling** | Tailwind CSS 4 | Rapid mobile-first UI development |
|
|
| **State Management** | Svelte 5 runes ($state, $derived, $effect) | Built-in, no external library needed |
|
|
| **Desktop (future)** | Tauri 2 | Rust backend, officially supports SvelteKit |
|
|
|
|
---
|
|
|
|
## 3. Data Model — Schema.org + Custom Ontology
|
|
|
|
### 3.1 Core Types
|
|
|
|
We use `schema:IndividualProduct` as the base type for tracked items. This is the correct schema.org type for "a single, identifiable product instance (e.g., a laptop with a particular serial number)."
|
|
|
|
#### Item (schema:IndividualProduct)
|
|
|
|
```turtle
|
|
@prefix schema: <https://schema.org/> .
|
|
@prefix solidhaus: <https://vocab.toph.so/solidhaus#> .
|
|
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
|
|
|
<https://pod.toph.so/inventory/items/za3rbam>
|
|
a schema:IndividualProduct ;
|
|
schema:identifier "za3rbam" ;
|
|
schema:name "Bosch Drill PSB 1800" ;
|
|
schema:description "Cordless drill, green, bought at Bauhaus" ;
|
|
schema:category "Tools" ;
|
|
schema:brand [ a schema:Brand ; schema:name "Bosch" ] ;
|
|
schema:image <https://pod.toph.so/inventory/photos/za3rbam_01.jpg> ;
|
|
schema:serialNumber "SN-483920" ;
|
|
schema:purchaseDate "2024-03-15"^^xsd:date ;
|
|
schema:color "Green" ;
|
|
|
|
# Custom properties for inventory tracking
|
|
solidhaus:shortId "za3rbam" ;
|
|
solidhaus:itemType solidhaus:Durable ;
|
|
solidhaus:barcodeFormat "qr" ;
|
|
solidhaus:barcodeUri "https://haus.toph.so/za3rbam" ;
|
|
|
|
# Location tracking (latest state)
|
|
solidhaus:lastSeenAt <https://pod.toph.so/inventory/locations/werkstatt> ;
|
|
solidhaus:lastSeenTimestamp "2026-02-20T14:30:00Z"^^xsd:dateTime ;
|
|
solidhaus:supposedToBeAt <https://pod.toph.so/inventory/locations/werkstatt-pegboard> ;
|
|
solidhaus:locationConfidence "confirmed" ;
|
|
|
|
# Custody state
|
|
solidhaus:custodyState solidhaus:CheckedIn ;
|
|
solidhaus:storageTier solidhaus:HotStorage .
|
|
```
|
|
|
|
#### Location (schema:Place)
|
|
|
|
```turtle
|
|
<https://pod.toph.so/inventory/locations/werkstatt>
|
|
a schema:Place ;
|
|
schema:name "Werkstatt" ;
|
|
schema:description "Basement workshop" ;
|
|
solidhaus:locationType "room" ;
|
|
solidhaus:defaultStorageTier solidhaus:HotStorage ;
|
|
schema:containedInPlace <https://pod.toph.so/inventory/locations/home> .
|
|
```
|
|
|
|
#### Sighting Event (schema:Action)
|
|
|
|
```turtle
|
|
<https://pod.toph.so/inventory/sightings/s_x7k9m2>
|
|
a solidhaus:SightingEvent, schema:FindAction ;
|
|
schema:object <https://pod.toph.so/inventory/items/za3rbam> ;
|
|
schema:location <https://pod.toph.so/inventory/locations/werkstatt> ;
|
|
schema:startTime "2026-02-20T14:30:00Z"^^xsd:dateTime ;
|
|
schema:agent <https://pod.toph.so/profile/card#me> ;
|
|
solidhaus:sightingType "scan" ;
|
|
solidhaus:confidence "confirmed" .
|
|
```
|
|
|
|
### 3.2 Custom Ontology: solidhaus
|
|
|
|
**Namespace:** `https://vocab.toph.so/solidhaus#`
|
|
|
|
Full ontology defined in `solidhaus.ttl`. Key terms:
|
|
|
|
| Term | Type | Description |
|
|
|------|------|-------------|
|
|
| `shortId` | Property | 7-char nanoid identifier |
|
|
| `barcodeUri` | Property | URI encoded in barcode |
|
|
| `itemType` | Property | durable, consumable, perishable, etc. |
|
|
| `custodyState` | Property | checked-in or checked-out |
|
|
| `storageTier` | Property | hot, warm, or cold |
|
|
| `lastSeenAt` | Property | Where item was last observed |
|
|
| `supposedToBeAt` | Property | Designated storage location |
|
|
| `checkedOutReason` | Property | in-use, lent, in-repair, etc. |
|
|
| `currentQuantity` | Property | Amount remaining (consumables) |
|
|
| `quantityUnit` | Property | ml, g, pcs, %, etc. |
|
|
| `lowThreshold` | Property | Alert threshold |
|
|
| `CheckOutEvent` | Class | Subclass of schema:CheckOutAction |
|
|
| `CheckInEvent` | Class | Subclass of schema:CheckInAction |
|
|
|
|
### 3.3 Item Types & Lifecycle
|
|
|
|
```typescript
|
|
type ItemType =
|
|
| 'durable' // Tools, furniture, electronics — long-lasting
|
|
| 'consumable' // Batteries, tape, screws — deplete with use
|
|
| 'disposable' // Paper plates, trash bags — single use
|
|
| 'perishable' // Food/drink with expiry dates
|
|
| 'media' // Books, DVDs, games
|
|
| 'clothing' // Wearable items
|
|
| 'document' // Papers, manuals, certificates
|
|
| 'container' // Boxes, bins — items that hold other items
|
|
;
|
|
```
|
|
|
|
Consumables and perishables have quantity tracking:
|
|
|
|
```typescript
|
|
interface QuantityInfo {
|
|
currentQuantity: number | null; // e.g., 750
|
|
originalQuantity: number | null; // e.g., 1000
|
|
quantityUnit: string; // "ml", "g", "pcs", "sheets", "%"
|
|
lowThreshold: number | null; // alert when below (e.g., 100)
|
|
expiryDate: string | null; // ISO date, for perishables
|
|
}
|
|
```
|
|
|
|
### 3.4 Location Hierarchy
|
|
|
|
Locations form a tree using `schema:containedInPlace`:
|
|
|
|
```
|
|
Home (Residence)
|
|
├── Erdgeschoss (Floor)
|
|
│ ├── Küche (Room)
|
|
│ │ ├── Schublade Links (Drawer)
|
|
│ │ └── Regal über Spüle (Shelf)
|
|
│ ├── Wohnzimmer (Room)
|
|
│ │ └── TV-Schrank (Furniture)
|
|
│ └── Flur (Room)
|
|
├── Obergeschoss (Floor)
|
|
│ ├── Schlafzimmer (Room)
|
|
│ ├── Büro (Room)
|
|
│ │ ├── Schreibtisch (Furniture)
|
|
│ │ └── Regal (Shelf)
|
|
│ └── Bad (Room)
|
|
└── Keller (Floor)
|
|
└── Werkstatt (Room)
|
|
├── Werkbank (Furniture)
|
|
└── Werkzeugwand (Storage)
|
|
```
|
|
|
|
### 3.5 Custody Model — Check-In / Check-Out
|
|
|
|
Items have a **custody state**:
|
|
|
|
| State | Meaning | Icon |
|
|
|-------|---------|------|
|
|
| **Checked In** | At designated storage location, put away | ✅ 📥 |
|
|
| **Checked Out** | Removed from storage | 🔄 📤 |
|
|
|
|
Check-out reasons:
|
|
|
|
| Reason | Example |
|
|
|--------|---------|
|
|
| **In Use** | Drill on workbench, book being read |
|
|
| **In Transit** | Carrying tools to another room |
|
|
| **Lent** | Lent to neighbor Max (records *who*) |
|
|
| **In Repair** | Sent to repair shop |
|
|
| **Temporary** | Moved for a project |
|
|
| **Consumed** | Used up or disposed of (terminal) |
|
|
|
|
#### RDF Example
|
|
|
|
```turtle
|
|
<items/za3rbam>
|
|
solidhaus:custodyState solidhaus:CheckedOut ;
|
|
solidhaus:checkedOutSince "2026-02-26T10:00:00Z"^^xsd:dateTime ;
|
|
solidhaus:checkedOutReason solidhaus:InUse ;
|
|
solidhaus:checkedOutFrom <locations/werkstatt-pegboard> ;
|
|
solidhaus:lastSeenAt <locations/werkstatt-workbench> ;
|
|
solidhaus:supposedToBeAt <locations/werkstatt-pegboard> ;
|
|
solidhaus:storageTier solidhaus:HotStorage .
|
|
```
|
|
|
|
### 3.6 Storage Tiers
|
|
|
|
| Tier | Name | Examples | Usage |
|
|
|------|------|----------|-------|
|
|
| 🔴 **Hot** | Active / Grab-and-go | Pegboard, desk, kitchen counter | Daily |
|
|
| 🟡 **Warm** | Nearby / Effort required | Cabinet, toolbox, high shelf | Weekly |
|
|
| 🔵 **Cold** | Deep / Archival | Attic boxes, basement bins | Seasonal |
|
|
|
|
For cold storage, `storageContainer` and `storageContainerLabel` track which box to dig out. Containers themselves can be tracked items.
|
|
|
|
### 3.7 Scan Actions (Context-Dependent)
|
|
|
|
**If item is Checked In:** "Check Out" | "Just Sighting" | "Move Storage"
|
|
**If item is Checked Out:** "Check In" | "Still Using" | "Change Location"
|
|
|
|
Confidence decays: ≤30d → confirmed, ≤90d → likely, ≤180d → assumed, >180d → unknown. Overdue items (checked out >7d) surface on dashboard.
|
|
|
|
---
|
|
|
|
## 4. ID Generation & URI Strategy
|
|
|
|
### 4.1 Nanoid Configuration
|
|
|
|
```typescript
|
|
import { customAlphabet } from 'nanoid';
|
|
const ALPHABET = '23456789abcdefghjkmnpqrstuvwxyz'; // no 0/o/1/i/l
|
|
const generateItemId = customAlphabet(ALPHABET, 7);
|
|
// Examples: "za3rbam", "k7xhw2n", "p4fvt8c"
|
|
```
|
|
|
|
30^7 ≈ 21.8 billion combinations. Lowercase for URI readability.
|
|
|
|
### 4.2 URI Scheme
|
|
|
|
**Canonical QR content:** `https://haus.toph.so/{id}`
|
|
|
|
Deep linking behavior:
|
|
1. **Native app installed (Capacitor):** App Links / Universal Links → opens app
|
|
2. **PWA installed on Android:** Chrome intercepts → opens PWA
|
|
3. **Nothing installed:** Opens browser → landing page
|
|
|
|
Additionally register `haus://` as custom scheme in Capacitor for direct launch.
|
|
|
|
### 4.3 ID Parsing
|
|
|
|
```typescript
|
|
export function parseItemId(rawValue: string): string | null {
|
|
const httpsMatch = rawValue.match(/haus\.toph\.so\/([23456789a-hjkmnp-z]{7})$/);
|
|
if (httpsMatch) return httpsMatch[1];
|
|
|
|
const schemeMatch = rawValue.match(/^haus:\/\/([23456789a-hjkmnp-z]{7})$/);
|
|
if (schemeMatch) return schemeMatch[1];
|
|
|
|
const rawMatch = rawValue.match(/^[23456789a-hjkmnp-z]{7}$/);
|
|
if (rawMatch) return rawMatch[0];
|
|
|
|
return null;
|
|
}
|
|
```
|
|
|
|
### 4.4 Pre-Printed Label Sheets
|
|
|
|
Batch-generate QR code sheets with unassigned IDs. Apply labels physically, then scan to associate.
|
|
|
|
**Workflow:**
|
|
1. Generate 50 new IDs → stored as "unassigned" in DB
|
|
2. Download PDF (A4 sticker sheet) or print tape strip
|
|
3. Apply labels to items
|
|
4. Scan label → "Create new item with ID za3rbam?" → enter details
|
|
|
|
---
|
|
|
|
## 5. Multi-User Offline-First Sync
|
|
|
|
### 5.1 Architecture: Automerge CRDT
|
|
|
|
```
|
|
Device A ←→ Automerge Sync Server (NixOS) ←→ Device B
|
|
│
|
|
▼
|
|
Solid Pod (periodic RDF export)
|
|
```
|
|
|
|
Each device maintains a local Automerge document. automerge-repo handles sync via WebSocket relay. Offline changes accumulate locally and merge conflict-free when reconnected.
|
|
|
|
Solid Pod serves as long-term RDF archive, not real-time sync layer.
|
|
|
|
### 5.2 Automerge Document Structure
|
|
|
|
```typescript
|
|
interface InventoryDoc {
|
|
items: { [shortId: string]: Item };
|
|
locations: { [id: string]: Location };
|
|
sightings: { [id: string]: Sighting };
|
|
preGeneratedIds: { [id: string]: PreGeneratedId };
|
|
}
|
|
```
|
|
|
|
### 5.3 Auth & Permissions
|
|
|
|
- Household members authenticate with Solid WebID
|
|
- Sync server: shared-secret or Solid-based auth
|
|
- Personal items can be `visibility: 'private'`
|
|
|
|
### 5.4 NextGraph (Future)
|
|
|
|
CRDT-native RDF with E2EE, P2P sync, SPARQL. Could replace Automerge + Solid if it reaches production.
|
|
|
|
---
|
|
|
|
## 6. Solid Pod Structure
|
|
|
|
```
|
|
/inventory/
|
|
├── ontology.ttl
|
|
├── items/
|
|
│ ├── za3rbam.ttl
|
|
│ └── k7xhw2n.ttl
|
|
├── locations/
|
|
│ ├── home.ttl
|
|
│ └── werkstatt.ttl
|
|
├── sightings/
|
|
│ └── 2026-02/
|
|
│ └── s_x7k9m2.ttl
|
|
└── photos/
|
|
└── za3rbam_01.jpg
|
|
```
|
|
|
|
---
|
|
|
|
## 7. Barcode Scanning
|
|
|
|
### 7.1 Capacitor ML Kit (Primary)
|
|
|
|
```typescript
|
|
import { BarcodeScanner, BarcodeFormat } from '@capacitor-mlkit/barcode-scanning';
|
|
|
|
const { barcodes } = await BarcodeScanner.scan({
|
|
formats: [BarcodeFormat.QrCode, BarcodeFormat.Code128, BarcodeFormat.DataMatrix],
|
|
});
|
|
```
|
|
|
|
### 7.2 Web Fallback
|
|
|
|
```typescript
|
|
if ('BarcodeDetector' in window) {
|
|
const detector = new BarcodeDetector({ formats: ['qr_code', 'code_128', 'data_matrix'] });
|
|
const barcodes = await detector.detect(videoFrame);
|
|
}
|
|
// Fallback: html5-qrcode (ZXing WASM) for Safari/Firefox
|
|
```
|
|
|
|
### 7.3 Deep Linking (Capacitor)
|
|
|
|
AndroidManifest.xml registers `haus://` scheme and `https://haus.toph.so` App Links. iOS Info.plist registers URL scheme + Associated Domains.
|
|
|
|
---
|
|
|
|
## 8. Label Generation & Printing
|
|
|
|
### 8.1 Pre-Generated ID Batches
|
|
|
|
IDs are allocated in batches (e.g., 50), stored as unassigned until scanned and linked to an item.
|
|
|
|
### 8.2 PDF Label Sheets
|
|
|
|
Generate A4 PDFs using Canvas API + jsPDF. Each cell: QR code + human-readable ID. Print on sticker paper.
|
|
|
|
### 8.3 Print Server (NixOS, Optional)
|
|
|
|
REST API for label tape printing. Accepts label data over HTTP, handles the printer protocol. Works from any device on LAN.
|
|
|
|
---
|
|
|
|
## 9. App Screens & User Flows
|
|
|
|
### 9.1 Main Screens
|
|
|
|
1. **Dashboard** — Stats, recent sightings, overdue items, low-stock consumables
|
|
2. **Scanner** — Camera + barcode detection
|
|
3. **Item Detail** — Info, photos, history, quantity
|
|
4. **Item Create/Edit** — Form with photo capture
|
|
5. **Location Browser** — Hierarchical tree
|
|
6. **Search** — Full-text search
|
|
7. **Label Sheets** — Generate and manage batches
|
|
8. **Settings** — Solid Pod, sync, household members
|
|
|
|
### 9.2 Key Flows
|
|
|
|
#### Scan & Check Out
|
|
```
|
|
Scan item → Card shows: ✅ Checked In at Pegboard (Hot)
|
|
→ Tap "Check Out" → reason: "In Use" → location: Workbench
|
|
→ 🔄 Checked Out (In Use) from Pegboard → at Workbench
|
|
```
|
|
|
|
#### Scan & Check In
|
|
```
|
|
Scan item → Card shows: 🔄 Checked Out since 2h ago
|
|
→ Tap "Check In" → confirm return to Pegboard
|
|
→ ✅ Checked In at Pegboard
|
|
```
|
|
|
|
#### Scan Pre-Printed Label → New Item
|
|
```
|
|
Scan unknown QR → ID recognized as pre-generated, unassigned
|
|
→ "Create new item?" → fill form → save → label associated
|
|
```
|
|
|
|
#### Quick Update Consumable
|
|
```
|
|
Scan olive oil → "400ml / 1000ml (40%)"
|
|
→ Quick: "Almost empty" | "Half left" | "Just opened"
|
|
→ Below threshold → "Add to shopping list?"
|
|
```
|
|
|
|
#### Walking Audit
|
|
```
|
|
Start Audit for "Büro" → shows expected items
|
|
→ Scan each → confirmed ✅
|
|
→ Summary: 12/15 confirmed, 3 missing
|
|
```
|
|
|
|
---
|
|
|
|
## 10. Implementation Phases
|
|
|
|
### Phase 1: Core MVP (2-3 weeks)
|
|
- [ ] SvelteKit + Capacitor + Tailwind scaffold
|
|
- [ ] IndexedDB data layer (items, locations, sightings)
|
|
- [ ] Item create/edit with photo capture
|
|
- [ ] 7-char nanoid + QR generation (bwip-js)
|
|
- [ ] Scanner (Capacitor ML Kit + Barcode Detection API fallback)
|
|
- [ ] Location hierarchy, check-in/check-out, sighting logging
|
|
- [ ] Basic search, offline support
|
|
|
|
### Phase 2: Multi-User Sync (1-2 weeks)
|
|
- [ ] Automerge doc structure + automerge-repo
|
|
- [ ] NixOS sync server, multi-device sync
|
|
|
|
### Phase 3: Solid Integration (1-2 weeks)
|
|
- [ ] Solid auth, RDF serialization, periodic export
|
|
- [ ] Pod structure, ACLs, ontology at vocab.toph.so
|
|
|
|
### Phase 4: Label Sheets (1 week)
|
|
- [ ] Pre-gen ID batches, A4 PDF generator
|
|
- [ ] Unassigned → item association flow
|
|
- [ ] Print server (NixOS, optional)
|
|
|
|
### Phase 5: Consumables & Pantry (1 week)
|
|
- [ ] Item types, quantity tracking, low-stock alerts, expiry dates
|
|
|
|
### Phase 6: Advanced (2+ weeks)
|
|
- [ ] Audit mode, confidence decay, stats, categories/tags, import/export
|
|
|
|
### Phase 7: Future
|
|
- [ ] NextGraph, NFC tags, desktop via Tauri 2, product barcode lookup
|
|
|
|
---
|
|
|
|
## 11. Key Dependencies
|
|
|
|
```json
|
|
{
|
|
"dependencies": {
|
|
"@inrupt/solid-client": "^2",
|
|
"@inrupt/solid-client-authn-browser": "^2",
|
|
"@automerge/automerge": "latest",
|
|
"@automerge/automerge-repo": "latest",
|
|
"@automerge/automerge-repo-network-websocket": "latest",
|
|
"@automerge/automerge-repo-storage-indexeddb": "latest",
|
|
"@capacitor/core": "^6",
|
|
"@capacitor-mlkit/barcode-scanning": "^6",
|
|
"nanoid": "^5",
|
|
"idb": "^8",
|
|
"bwip-js": "^4",
|
|
"date-fns": "^4",
|
|
"jspdf": "^2"
|
|
},
|
|
"devDependencies": {
|
|
"@sveltejs/adapter-static": "latest",
|
|
"tailwindcss": "^4",
|
|
"@tailwindcss/vite": "latest",
|
|
"typescript": "^5.7"
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 12. Project Structure
|
|
|
|
```
|
|
solidhaus/
|
|
├── src/
|
|
│ ├── routes/
|
|
│ │ ├── +layout.svelte # App shell, bottom nav
|
|
│ │ ├── +layout.ts # SSR disabled
|
|
│ │ ├── +page.svelte # Dashboard
|
|
│ │ ├── scan/+page.svelte
|
|
│ │ ├── items/
|
|
│ │ │ ├── +page.svelte
|
|
│ │ │ ├── new/+page.svelte
|
|
│ │ │ └── [id]/+page.svelte
|
|
│ │ ├── locations/+page.svelte
|
|
│ │ ├── labels/+page.svelte
|
|
│ │ └── settings/+page.svelte
|
|
│ ├── lib/
|
|
│ │ ├── components/ # .svelte files
|
|
│ │ ├── data/ # IndexedDB layer
|
|
│ │ ├── sync/ # Automerge + Solid export
|
|
│ │ ├── solid/ # Solid auth, RDF, pod
|
|
│ │ ├── scanning/ # Barcode detection + parsing
|
|
│ │ ├── printing/ # Label PDF gen, print server
|
|
│ │ ├── stores/ # Svelte 5 rune stores
|
|
│ │ ├── types/ # TypeScript types
|
|
│ │ ├── ontology/ # Namespace constants
|
|
│ │ └── utils/ # ID gen, confidence, formatting
|
|
│ └── app.html
|
|
├── static/
|
|
├── ontology/solidhaus.ttl
|
|
├── android/ # Capacitor
|
|
├── ios/ # Capacitor
|
|
├── svelte.config.js
|
|
├── capacitor.config.ts
|
|
├── vite.config.ts
|
|
└── package.json
|
|
```
|
|
|
|
---
|
|
|
|
## 13. Schema.org Actions
|
|
|
|
```turtle
|
|
<sighting_xyz> a schema:UseAction ;
|
|
schema:object <item/za3rbam> ;
|
|
schema:agent <profile/card#me> ;
|
|
schema:startTime "2026-02-20T14:30:00Z" ;
|
|
schema:location <locations/werkstatt> .
|
|
|
|
<sighting_abc> a schema:MoveAction ;
|
|
schema:object <item/za3rbam> ;
|
|
schema:fromLocation <locations/werkstatt> ;
|
|
schema:toLocation <locations/buero> ;
|
|
schema:startTime "2026-02-21T09:00:00Z" .
|
|
```
|
|
|
|
---
|
|
|
|
## 14. Design System
|
|
|
|
**Dark theme (slate-based):** bg slate-900, surface slate-800, primary blue-500, confirmed emerald-500, warning amber-500, danger red-500.
|
|
|
|
**Mobile:** touch targets ≥44px, bottom sheet modals, haptic on scan (Capacitor Haptics), large monospace for IDs.
|
|
|
|
---
|
|
|
|
## 15. References
|
|
|
|
- **Solid**: solidproject.org, docs.inrupt.com, CommunitySolidServer
|
|
- **Schema.org**: IndividualProduct, Place, FindAction, CheckInAction, CheckOutAction
|
|
- **SvelteKit + Capacitor**: svelte.dev/docs/kit, capacitorjs.com, v2.tauri.app
|
|
- **CRDT**: automerge.org, nextgraph.org
|
|
- **Barcode**: MDN BarcodeDetector, bwip-js, html5-qrcode
|