Repository navigation
Expand file tree
/
Copy pathexample.config.json
More file actions
122 lines (122 loc) · 4.28 KB
/
Copy pathexample.config.json
File metadata and controls
122 lines (122 loc) · 4.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
{
"project_name": "Deal Tracker",
"project_description": "Fictional price-tracking pipeline used as the Mission_Control demo. Scrapes prices, ranks deals, mails alerts.",
"current_phase": "Onboarding fourth supplier source",
"overall_health": 78,
"last_synced_at": "2026-05-27T11:55:00Z",
"project_root": "~/projects/deal-tracker",
"readiness": {
"has_readme": true,
"env_safe": true,
"tests": true
},
"components": [
{
"id": "data_scraper",
"name": "Data scraper",
"description": "Pulls listings from 4 sources every 15 min",
"purpose": "Grabs current product listings from 4 supplier websites on a 15-min schedule",
"status": "warning",
"progress": 100,
"type": "scraper",
"tags": ["has-scraper"]
},
{
"id": "price_store",
"name": "Price store",
"description": "Postgres with 30d price history",
"purpose": "Keeps the last 30 days of prices so we can spot real drops vs normal swings",
"status": "healthy",
"progress": 100,
"type": "database"
},
{
"id": "rest_api",
"name": "REST API",
"description": "Public endpoints, served via FastAPI",
"purpose": "The public endpoints that web and mobile clients call to fetch prices and picks",
"status": "healthy",
"progress": 100,
"type": "api"
},
{
"id": "ranker_service",
"name": "Ranker service",
"description": "LLM-backed picks engine, 16 workers",
"purpose": "Uses an LLM to rank which deals are actually worth showing today",
"status": "healthy",
"progress": 80,
"type": "service",
"tags": ["uses-LLM"]
},
{
"id": "web_ui",
"name": "Web UI",
"description": "Next.js dashboard at /app",
"purpose": "The dashboard customers see in their browser at /app",
"status": "healthy",
"progress": 100,
"type": "frontend"
},
{
"id": "mail_relay",
"name": "Mail relay",
"description": "Transactional mail uplink for alerts",
"purpose": "Sends price-drop alert emails to subscribers",
"status": "broken",
"progress": 0,
"type": "external"
},
{
"id": "nightly_etl",
"name": "Nightly ETL",
"description": "Cron at 03:00 — full reindex",
"purpose": "3 a.m. job that rebuilds search indexes and refreshes derived tables",
"status": "healthy",
"progress": 100,
"type": "job"
},
{
"id": "scoring_lib",
"name": "Scoring lib",
"description": "Internal package — score normalization",
"purpose": "Shared math library — turns raw price moves into 0–100 deal scores",
"status": "healthy",
"progress": 100,
"type": "module"
}
],
"connections": [
{ "from": "data_scraper", "to": "price_store", "label": "raw listings" },
{ "from": "price_store", "to": "ranker_service", "label": "price history" },
{ "from": "ranker_service", "to": "rest_api", "label": "picks" },
{ "from": "rest_api", "to": "web_ui", "label": "JSON" },
{ "from": "ranker_service", "to": "mail_relay", "label": "alert" },
{ "from": "nightly_etl", "to": "price_store", "label": "reindex" },
{ "from": "scoring_lib", "to": "ranker_service", "label": "scores" }
],
"findings": [
{
"id": "f1",
"severity": "CRITICAL",
"component_id": "mail_relay",
"issue": "Mail provider returns 401 — token rotated last week, env not updated",
"impact": "Price-drop alerts have not gone out for 6 days; subscribers are missing the deals they signed up for",
"proposed_fix": "Update MAIL_TOKEN env var on the running service from the new value in the secrets vault",
"file": "infra/env.example.md:14",
"created_at": "2026-05-26T09:14:00Z",
"status": "open"
},
{
"id": "f2",
"severity": "SUGGESTION",
"component_id": "data_scraper",
"issue": "Source #3 occasionally rate-limits; retry backoff is fixed at 5s",
"impact": "When the source rate-limits, the scraper retries hot and gets banned for an hour, missing one full window of prices",
"proposed_fix": "Switch to exponential backoff with jitter, cap at 60s",
"file": "scraper/source3.py",
"created_at": "2026-05-26T09:14:00Z",
"status": "open"
}
]
}