feat: Add Cantaloupe sync API with staged import workflow
- New cantaloupe_sync.py module with complete pipeline - Heuristic Excel column mapping (20+ keyword patterns) - Diff engine: detects new/changed/removed/unchanged assets - 5 API endpoints: sync, list batches, view batch, approve, reject - cantaloupe_sync_batches table with status workflow - Admin server port changed to 8090 - openpyxl added to requirements.txt
This commit is contained in:
@@ -26,6 +26,8 @@ from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.responses import JSONResponse, StreamingResponse
|
||||
from pydantic import BaseModel
|
||||
|
||||
from cantaloupe_sync import router as cantaloupe_router, create_sync_tables
|
||||
|
||||
# ─── Config ─────────────────────────────────────────────────────────────────
|
||||
|
||||
VALID_CATEGORIES = {"Furniture", "Appliances", "Utensils & Serveware", "Equipment", "Other"}
|
||||
@@ -241,10 +243,24 @@ def _create_tables(conn: sqlite3.Connection):
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS cantaloupe_sync_batches (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
status TEXT NOT NULL DEFAULT 'pending',
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
approved_at TEXT,
|
||||
file_path TEXT,
|
||||
row_count INTEGER DEFAULT 0,
|
||||
diff_summary TEXT,
|
||||
raw_data TEXT,
|
||||
error_message TEXT
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_checkins_asset_id ON checkins(asset_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_checkins_created_at ON checkins(created_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_assets_category ON assets(category);
|
||||
CREATE INDEX IF NOT EXISTS idx_assets_machine_id ON assets(machine_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_csb_status ON cantaloupe_sync_batches(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_csb_created ON cantaloupe_sync_batches(created_at);
|
||||
""")
|
||||
|
||||
|
||||
@@ -293,6 +309,7 @@ def _seed_data(conn: sqlite3.Connection):
|
||||
def init_db(conn: sqlite3.Connection):
|
||||
"""Ensure all tables exist, run migrations if needed, seed default data."""
|
||||
_create_tables(conn)
|
||||
create_sync_tables(conn)
|
||||
_seed_data(conn)
|
||||
# Add lat/lng columns if missing (v3 migration)
|
||||
cursor = conn.execute("PRAGMA table_info(assets)")
|
||||
@@ -334,6 +351,9 @@ app.add_middleware(
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
# Mount Cantaloupe sync routes
|
||||
app.include_router(cantaloupe_router)
|
||||
|
||||
|
||||
# ─── Auth Middleware ────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
Reference in New Issue
Block a user