mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
refactor(tours): the region repository reads the status enum of its entity, unused exports go
PaddleRegionsRepository types and writes the status through the generated PaddleRegionsStatus instead of a copy of its four values; the paint tokens, a fact key type and a minutes input stay private to their modules, the wind test pins its 502 text, and the planner page's size entry follows it down.
This commit is contained in:
@@ -24,7 +24,7 @@
|
||||
"src/mobile/screens/admin/MAdminPluginsPanel.tsx": 1507,
|
||||
"src/pages/JourneyDetailPage.test.tsx": 4030,
|
||||
"src/pages/LoginPage.tsx": 1348,
|
||||
"src/pages/TripPlannerPage.tsx": 1147,
|
||||
"src/pages/TripPlannerPage.tsx": 1142,
|
||||
"src/pages/atlas/useAtlas.ts": 1287,
|
||||
"src/pages/tripPlanner/useTripPlanner.roadtrip.test.tsx": 3518,
|
||||
"src/pages/tripPlanner/useTripPlanner.test.tsx": 3309,
|
||||
|
||||
@@ -36,7 +36,7 @@ export function PaddleRolePill({ role }: { role: PaddleRole }) {
|
||||
* whole number of minutes in range is dropped on leaving the field, and the
|
||||
* value before it stays.
|
||||
*/
|
||||
export function MinutesInput({
|
||||
function MinutesInput({
|
||||
label,
|
||||
value,
|
||||
placeholder,
|
||||
|
||||
@@ -26,7 +26,7 @@ export const OBSTACLE_FACT_KEYS = [
|
||||
'fee',
|
||||
'operator',
|
||||
] as const;
|
||||
export type ObstacleFactKey = (typeof OBSTACLE_FACT_KEYS)[number];
|
||||
type ObstacleFactKey = (typeof OBSTACLE_FACT_KEYS)[number];
|
||||
|
||||
/** The access values the card puts into words; any other value is shown as OSM has it. */
|
||||
export const KNOWN_ACCESS_VALUES = ['yes', 'no', 'private', 'permissive', 'designated'] as const;
|
||||
|
||||
@@ -7,7 +7,7 @@ import { useMapPaint } from '../../Map/mapPaint';
|
||||
* reads them resolved (`usePaddlePaint`); markup on the page takes the CSS
|
||||
* variable itself (`paddleKindCss`), which follows the theme on its own.
|
||||
*/
|
||||
export const PADDLE_PAINT_TOKENS = {
|
||||
const PADDLE_PAINT_TOKENS = {
|
||||
obstacle: '--map-paddle-obstacle',
|
||||
access: '--map-paddle-access',
|
||||
landing: '--map-paddle-landing',
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import type { PaddleRegions } from '../entities/PaddleRegions.entity';
|
||||
import { type PaddleRegions, PaddleRegionsStatus, type TPaddleRegionsStatus } from '../entities/PaddleRegions.entity';
|
||||
import type { DB } from '../kysely/db';
|
||||
import type { Box } from './PaddleFeatures.repository';
|
||||
import { TrekRepository } from './_shared/trek-repository';
|
||||
|
||||
export type PaddleRegionStatus = 'queued' | 'importing' | 'ready' | 'failed';
|
||||
|
||||
/** One region an admin chose, as stored; the boundary is still GeoJSON text. */
|
||||
export interface PaddleRegionRow {
|
||||
id: string;
|
||||
@@ -14,7 +12,7 @@ export interface PaddleRegionRow {
|
||||
min_lng: number | null;
|
||||
max_lat: number | null;
|
||||
max_lng: number | null;
|
||||
status: PaddleRegionStatus;
|
||||
status: TPaddleRegionsStatus;
|
||||
source_timestamp: string | null;
|
||||
imported_at: string | null;
|
||||
feature_count: number;
|
||||
@@ -23,7 +21,7 @@ export interface PaddleRegionRow {
|
||||
|
||||
/** `status` narrowed to the four values the column's CHECK constraint allows. */
|
||||
type RegionsDB = {
|
||||
paddle_regions: Omit<DB['paddle_regions'], 'status'> & { status: PaddleRegionStatus };
|
||||
paddle_regions: Omit<DB['paddle_regions'], 'status'> & { status: TPaddleRegionsStatus };
|
||||
};
|
||||
|
||||
const COLUMNS = [
|
||||
@@ -78,7 +76,7 @@ export class PaddleRegionsRepository extends TrekRepository<PaddleRegions> {
|
||||
return await this.db()
|
||||
.selectFrom('paddle_regions')
|
||||
.select(COLUMNS)
|
||||
.where('status', '=', 'queued')
|
||||
.where('status', '=', PaddleRegionsStatus.QUEUED)
|
||||
.orderBy('created_at', 'asc')
|
||||
.executeTakeFirst();
|
||||
}
|
||||
@@ -88,7 +86,7 @@ export class PaddleRegionsRepository extends TrekRepository<PaddleRegions> {
|
||||
): Promise<void> {
|
||||
await this.db()
|
||||
.insertInto('paddle_regions')
|
||||
.values({ ...row, status: 'queued', feature_count: 0 })
|
||||
.values({ ...row, status: PaddleRegionsStatus.QUEUED, feature_count: 0 })
|
||||
.onConflict((oc) => oc.column('id').doNothing())
|
||||
.execute();
|
||||
}
|
||||
@@ -117,15 +115,19 @@ export class PaddleRegionsRepository extends TrekRepository<PaddleRegions> {
|
||||
async queueReady(): Promise<number> {
|
||||
const result = await this.db()
|
||||
.updateTable('paddle_regions')
|
||||
.set({ status: 'queued', error: null })
|
||||
.where('status', 'in', ['ready', 'failed'])
|
||||
.set({ status: PaddleRegionsStatus.QUEUED, error: null })
|
||||
.where('status', 'in', [PaddleRegionsStatus.READY, PaddleRegionsStatus.FAILED])
|
||||
.executeTakeFirst();
|
||||
return Number(result.numUpdatedRows ?? 0);
|
||||
}
|
||||
|
||||
/** A region left half read by a restart goes back to the queue. */
|
||||
async requeueInterrupted(): Promise<void> {
|
||||
await this.db().updateTable('paddle_regions').set({ status: 'queued' }).where('status', '=', 'importing').execute();
|
||||
await this.db()
|
||||
.updateTable('paddle_regions')
|
||||
.set({ status: PaddleRegionsStatus.QUEUED })
|
||||
.where('status', '=', PaddleRegionsStatus.IMPORTING)
|
||||
.execute();
|
||||
}
|
||||
|
||||
async deleteRegion(id: string): Promise<boolean> {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* request is a 502 of its own rather than an empty forecast.
|
||||
*/
|
||||
import { DomainError } from '../../../../src/nest/common/domain-error';
|
||||
import { WindService } from '../../../../src/nest/weather/wind.service';
|
||||
import { WIND_UNAVAILABLE_MESSAGE, WindService } from '../../../../src/nest/weather/wind.service';
|
||||
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
@@ -97,6 +97,8 @@ describe('WindService', () => {
|
||||
vi.stubGlobal('fetch', answer({ hourly: 'nonsense' }));
|
||||
await expect(service.forecast({ lat: 47, lng: 9, date: '2026-10-19' }, NOW)).rejects.toMatchObject({
|
||||
code: 'wind_unavailable',
|
||||
status: 502,
|
||||
publicMessage: WIND_UNAVAILABLE_MESSAGE,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user