fix(wds): auto-initialize queue with default cities on first access
The /wds page was showing 0 cities because the KeyValueStore was empty until the scheduler ran for the first time. Now the GET endpoint initializes the queue with the 9 default cities on first access. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -26,22 +26,58 @@ type WeekendSyncState = {
|
|||||||
completedCycles: number;
|
completedCycles: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const FRESH_STEPS: Record<StepName, StepStatus> = {
|
||||||
|
sync_terenuri: "pending",
|
||||||
|
sync_cladiri: "pending",
|
||||||
|
import_nogeom: "pending",
|
||||||
|
enrich: "pending",
|
||||||
|
};
|
||||||
|
|
||||||
|
const DEFAULT_CITIES: Omit<CityState, "steps">[] = [
|
||||||
|
{ siruta: "54975", name: "Cluj-Napoca", county: "Cluj", priority: 1 },
|
||||||
|
{ siruta: "32394", name: "Bistri\u021Ba", county: "Bistri\u021Ba-N\u0103s\u0103ud", priority: 1 },
|
||||||
|
{ siruta: "114319", name: "T\u00E2rgu Mure\u0219", county: "Mure\u0219", priority: 2 },
|
||||||
|
{ siruta: "139704", name: "Zal\u0103u", county: "S\u0103laj", priority: 2 },
|
||||||
|
{ siruta: "26564", name: "Oradea", county: "Bihor", priority: 2 },
|
||||||
|
{ siruta: "9262", name: "Arad", county: "Arad", priority: 2 },
|
||||||
|
{ siruta: "155243", name: "Timi\u0219oara", county: "Timi\u0219", priority: 2 },
|
||||||
|
{ siruta: "143450", name: "Sibiu", county: "Sibiu", priority: 2 },
|
||||||
|
{ siruta: "40198", name: "Bra\u0219ov", county: "Bra\u0219ov", priority: 2 },
|
||||||
|
];
|
||||||
|
|
||||||
|
/** Initialize state with default cities if not present in DB */
|
||||||
|
async function getOrCreateState(): Promise<WeekendSyncState> {
|
||||||
|
const row = await prisma.keyValueStore.findUnique({
|
||||||
|
where: { namespace_key: { namespace: KV_NAMESPACE, key: KV_KEY } },
|
||||||
|
});
|
||||||
|
if (row?.value && typeof row.value === "object") {
|
||||||
|
return row.value as unknown as WeekendSyncState;
|
||||||
|
}
|
||||||
|
// First access — initialize with defaults
|
||||||
|
const state: WeekendSyncState = {
|
||||||
|
cities: DEFAULT_CITIES.map((c) => ({ ...c, steps: { ...FRESH_STEPS } })),
|
||||||
|
totalSessions: 0,
|
||||||
|
completedCycles: 0,
|
||||||
|
};
|
||||||
|
await prisma.keyValueStore.upsert({
|
||||||
|
where: { namespace_key: { namespace: KV_NAMESPACE, key: KV_KEY } },
|
||||||
|
update: { value: state as unknown as Prisma.InputJsonValue },
|
||||||
|
create: {
|
||||||
|
namespace: KV_NAMESPACE,
|
||||||
|
key: KV_KEY,
|
||||||
|
value: state as unknown as Prisma.InputJsonValue,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET /api/eterra/weekend-sync
|
* GET /api/eterra/weekend-sync
|
||||||
* Returns the current queue state.
|
* Returns the current queue state.
|
||||||
*/
|
*/
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
// Auth handled by middleware (route is not excluded)
|
// Auth handled by middleware (route is not excluded)
|
||||||
const row = await prisma.keyValueStore.findUnique({
|
const state = await getOrCreateState();
|
||||||
where: { namespace_key: { namespace: KV_NAMESPACE, key: KV_KEY } },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!row?.value) {
|
|
||||||
return NextResponse.json({ state: null });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enrich with DB feature counts per city
|
|
||||||
const state = row.value as unknown as WeekendSyncState;
|
|
||||||
const sirutas = state.cities.map((c) => c.siruta);
|
const sirutas = state.cities.map((c) => c.siruta);
|
||||||
|
|
||||||
const counts = await prisma.gisFeature.groupBy({
|
const counts = await prisma.gisFeature.groupBy({
|
||||||
@@ -99,21 +135,7 @@ export async function POST(request: Request) {
|
|||||||
priority?: number;
|
priority?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Load current state
|
const state = await getOrCreateState();
|
||||||
const row = await prisma.keyValueStore.findUnique({
|
|
||||||
where: { namespace_key: { namespace: KV_NAMESPACE, key: KV_KEY } },
|
|
||||||
});
|
|
||||||
|
|
||||||
const state: WeekendSyncState = row?.value
|
|
||||||
? (row.value as unknown as WeekendSyncState)
|
|
||||||
: { cities: [], totalSessions: 0, completedCycles: 0 };
|
|
||||||
|
|
||||||
const freshSteps: Record<StepName, StepStatus> = {
|
|
||||||
sync_terenuri: "pending",
|
|
||||||
sync_cladiri: "pending",
|
|
||||||
import_nogeom: "pending",
|
|
||||||
enrich: "pending",
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (body.action) {
|
switch (body.action) {
|
||||||
case "add": {
|
case "add": {
|
||||||
@@ -134,7 +156,7 @@ export async function POST(request: Request) {
|
|||||||
name: body.name,
|
name: body.name,
|
||||||
county: body.county ?? "",
|
county: body.county ?? "",
|
||||||
priority: body.priority ?? 3,
|
priority: body.priority ?? 3,
|
||||||
steps: { ...freshSteps },
|
steps: { ...FRESH_STEPS },
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -145,14 +167,14 @@ export async function POST(request: Request) {
|
|||||||
case "reset": {
|
case "reset": {
|
||||||
const city = state.cities.find((c) => c.siruta === body.siruta);
|
const city = state.cities.find((c) => c.siruta === body.siruta);
|
||||||
if (city) {
|
if (city) {
|
||||||
city.steps = { ...freshSteps };
|
city.steps = { ...FRESH_STEPS };
|
||||||
city.errorMessage = undefined;
|
city.errorMessage = undefined;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "reset_all": {
|
case "reset_all": {
|
||||||
for (const city of state.cities) {
|
for (const city of state.cities) {
|
||||||
city.steps = { ...freshSteps };
|
city.steps = { ...FRESH_STEPS };
|
||||||
city.errorMessage = undefined;
|
city.errorMessage = undefined;
|
||||||
}
|
}
|
||||||
state.completedCycles = 0;
|
state.completedCycles = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user