Compare commits
1 Commits
506ac612bc
...
chore/patc
| Author | SHA1 | Date | |
|---|---|---|---|
| 457722a79c |
47
.github/workflows/deploy-coolify.yml
vendored
47
.github/workflows/deploy-coolify.yml
vendored
@@ -1,47 +0,0 @@
|
|||||||
name: "Deploy to Coolify"
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
deploy:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Check out repository
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Login to Gitea Container Registry
|
|
||||||
uses: docker/login-action@v4
|
|
||||||
with:
|
|
||||||
registry: gitea.bchen.dev
|
|
||||||
username: ${{ github.actor }}
|
|
||||||
password: ${{ secrets.PAT }}
|
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v4
|
|
||||||
|
|
||||||
- name: Build and push
|
|
||||||
uses: docker/build-push-action@v7
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
push: true
|
|
||||||
tags: gitea.bchen.dev/${{ github.actor }}/project-inter-server:latest
|
|
||||||
|
|
||||||
- name: Set up Tailscale
|
|
||||||
uses: tailscale/github-action@v4
|
|
||||||
with:
|
|
||||||
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
|
|
||||||
oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
|
|
||||||
tags: tag:ci
|
|
||||||
use-cache: false
|
|
||||||
tailscaled-args: --tun=userspace-networking --socks5-server=localhost:1055 --outbound-http-proxy-listen=localhost:1055
|
|
||||||
|
|
||||||
- name: Deploy to Coolify
|
|
||||||
run: |
|
|
||||||
curl --request POST '${{ secrets.COOLIFY_WEBHOOK }}' --header 'Authorization: Bearer ${{ secrets.COOLIFY_TOKEN }}'
|
|
||||||
60
.github/workflows/deploy.yml
vendored
Normal file
60
.github/workflows/deploy.yml
vendored
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
name: "Deploy to birb co."
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Check out repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
# See documentation: https://github.com/tailscale/github-action?tab=readme-ov-file
|
||||||
|
- name: Connect to Tailscale
|
||||||
|
uses: tailscale/github-action@v4
|
||||||
|
with:
|
||||||
|
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
|
||||||
|
oauth-secret: ${{ secrets.TS_OAUTH_CLIENT_SECRET }}
|
||||||
|
tags: tag:ci
|
||||||
|
|
||||||
|
- name: Set up SSH key
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
|
||||||
|
chmod 600 ~/.ssh/id_ed25519
|
||||||
|
ssh-keyscan ${{ vars.HOST }} >> ~/.ssh/known_hosts
|
||||||
|
|
||||||
|
- name: Remove directory from server
|
||||||
|
run: |
|
||||||
|
ssh -i ~/.ssh/id_ed25519 ${{ vars.USERNAME }}@${{ vars.HOST }} << 'EOF'
|
||||||
|
rm -rf ~/${{ vars.DIRECTORY_NAME }}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Avoid needing to set up SSH access to GitHub for this user
|
||||||
|
- name: Transfer repository files to server
|
||||||
|
run: |
|
||||||
|
scp -i ~/.ssh/id_ed25519 -r ./* ${{ vars.USERNAME }}@${{ vars.HOST }}:~/${{ vars.DIRECTORY_NAME }}
|
||||||
|
|
||||||
|
- name: Deploy on server with Docker
|
||||||
|
run: |
|
||||||
|
ssh -i ~/.ssh/id_ed25519 ${{ vars.USERNAME }}@${{ vars.HOST }} << 'EOF'
|
||||||
|
cd ~/${{ vars.DIRECTORY_NAME }}
|
||||||
|
export APNS_IS_PRODUCTION=${{ secrets.APNS_IS_PRODUCTION }}
|
||||||
|
export APNS_BUNDLE_ID=${{ secrets.APNS_BUNDLE_ID }}
|
||||||
|
export APNS_TEAM_ID=${{ secrets.APNS_TEAM_ID }}
|
||||||
|
export APNS_KEY_ID=${{ secrets.APNS_KEY_ID }}
|
||||||
|
export APNS_PRIVATE_KEY=${{ secrets.APNS_PRIVATE_KEY }}
|
||||||
|
export PARKING_LOGGING_INTERVAL_MS=${{ secrets.PARKING_LOGGING_INTERVAL_MS }}
|
||||||
|
export RATE_LIMITS_DISABLED=${{ secrets.RATE_LIMITS_DISABLED }}
|
||||||
|
export RATE_LIMIT_WINDOW_MS=${{ secrets.RATE_LIMIT_WINDOW_MS }}
|
||||||
|
export RATE_LIMIT_DELAY_AFTER_REQUESTS=${{ secrets.RATE_LIMIT_DELAY_AFTER_REQUESTS }}
|
||||||
|
export RATE_LIMIT_DELAY_MULTIPLIER_MS=${{ secrets.RATE_LIMIT_DELAY_MULTIPLIER_MS }}
|
||||||
|
export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock
|
||||||
|
docker compose -f docker-compose.prod.yml down --remove-orphans
|
||||||
|
docker compose -f docker-compose.prod.yml up -d --build
|
||||||
|
EOF
|
||||||
103
AGENTS.md
103
AGENTS.md
@@ -1,103 +0,0 @@
|
|||||||
# CLAUDE.md
|
|
||||||
|
|
||||||
This file provides guidance to all agents when working with code in this repository.
|
|
||||||
|
|
||||||
## Development Commands
|
|
||||||
|
|
||||||
### Core Development
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Start development server with hot reloading
|
|
||||||
docker compose run dev
|
|
||||||
|
|
||||||
# Run comprehensive test suite
|
|
||||||
docker compose run test
|
|
||||||
|
|
||||||
# Generate GraphQL TypeScript types
|
|
||||||
npm run generate
|
|
||||||
|
|
||||||
# Build for development (install, codegen, tsc)
|
|
||||||
npm run build:dev
|
|
||||||
```
|
|
||||||
|
|
||||||
Only use Docker Compose for running tests, and only use `docker compose run test`
|
|
||||||
to run tests; don't try to run tests for individual files.
|
|
||||||
|
|
||||||
## Architecture Overview
|
|
||||||
|
|
||||||
Project Inter Server is a GraphQL-based backend for college transit tracking with real-time shuttle data, parking availability, and push notifications.
|
|
||||||
|
|
||||||
- InterchangeSystem: Central orchestrator for shuttles, parking, and notifications
|
|
||||||
- Use `InterchangeSystem.build()` in production
|
|
||||||
- Use `InterchangeSystem.buildForTesting()` in tests
|
|
||||||
|
|
||||||
- Repository Pattern (data access abstraction)
|
|
||||||
- Shuttle: `UnoptimizedInMemoryShuttleRepository`
|
|
||||||
- Parking: `InMemoryParkingRepository`
|
|
||||||
- Notifications: `RedisNotificationRepository` (prod) / `InMemoryNotificationRepository` (test)
|
|
||||||
|
|
||||||
- Data Loaders (external API integration)
|
|
||||||
- `ApiBasedShuttleRepositoryLoader` – Passio GO! API
|
|
||||||
- `ChapmanApiBasedParkingRepositoryLoader` – Parking data
|
|
||||||
- `TimedApiBasedRepositoryLoader` – Periodic refresh wrapper
|
|
||||||
|
|
||||||
- Notification System
|
|
||||||
- `ETANotificationScheduler` – Shuttle arrival notifications
|
|
||||||
- `AppleNotificationSender` – APNS integration
|
|
||||||
|
|
||||||
## GraphQL
|
|
||||||
|
|
||||||
- Schema definition: `schema.graphqls`
|
|
||||||
- Generated types: `src/generated/`
|
|
||||||
- Resolvers: `src/resolvers/`
|
|
||||||
- Resolver merge: `src/MergedResolvers.ts`
|
|
||||||
|
|
||||||
## Directory Structure
|
|
||||||
|
|
||||||
- `src/entities/` – Core business logic
|
|
||||||
- `src/repositories/` – Data access layer
|
|
||||||
- `src/loaders/` – External API integrations
|
|
||||||
- `src/notifications/` – Push notification system
|
|
||||||
- `src/resolvers/` – GraphQL resolvers and tests
|
|
||||||
- `testHelpers/` – Test utilities and mock data
|
|
||||||
|
|
||||||
## Docker Services
|
|
||||||
|
|
||||||
- `dev` – Development server with hot reload
|
|
||||||
- `test` – Unit/integration tests
|
|
||||||
- `redis` – Persistent Redis
|
|
||||||
- `redis-no-persistence` – Ephemeral Redis for tests
|
|
||||||
|
|
||||||
## Testing Patterns
|
|
||||||
|
|
||||||
- Prefer `buildForTesting()` to construct systems in tests.
|
|
||||||
- Mock external APIs using JSON snapshots under `testHelpers/jsonSnapshots`.
|
|
||||||
- Use in-memory repositories for speed where possible.
|
|
||||||
- When adding features that affect API output, add focused resolver tests in the corresponding `src/resolvers/__tests__` file.
|
|
||||||
- Separate unit tests from integration tests where practical to keep feedback fast and failures well-scoped.
|
|
||||||
|
|
||||||
## Development Guidelines
|
|
||||||
|
|
||||||
### General Guidelines
|
|
||||||
|
|
||||||
- Use test-driven development where possible. Write tests before implementation and run them before and after changes.
|
|
||||||
- Use Docker Compose for tests. Run `docker compose run test` so you can see full output.
|
|
||||||
|
|
||||||
### Git Workflow
|
|
||||||
|
|
||||||
- Name pull requests after their branch name.
|
|
||||||
|
|
||||||
### Code Style
|
|
||||||
|
|
||||||
- Prefer arrow functions, especially within classes.
|
|
||||||
- Keep changes minimal and focused; avoid unrelated refactors. Mention incidental issues separately.
|
|
||||||
- Respect existing interfaces and types; use non-destructive edits.
|
|
||||||
|
|
||||||
### Agent Tips
|
|
||||||
|
|
||||||
- Write or update tests alongside changes; validate with `docker compose run test`.
|
|
||||||
- When touching GraphQL resolvers, co-locate new tests in `src/resolvers/__tests__`.
|
|
||||||
|
|
||||||
## Multi-tenant Support
|
|
||||||
|
|
||||||
Currently supports Chapman University (Passio System ID: `263`). Each university system uses isolated repositories and configuration. New systems should be added via `InterchangeSystem` configuration and appropriate loaders.
|
|
||||||
94
CLAUDE.md
94
CLAUDE.md
@@ -1 +1,93 @@
|
|||||||
See AGENTS.md
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code when working with code in this repository.
|
||||||
|
|
||||||
|
## Development Commands
|
||||||
|
|
||||||
|
### Core Development
|
||||||
|
```bash
|
||||||
|
# Start development server with hot reloading
|
||||||
|
docker compose run dev
|
||||||
|
|
||||||
|
# Run comprehensive test suite
|
||||||
|
docker compose run test
|
||||||
|
|
||||||
|
# Generate GraphQL TypeScript types
|
||||||
|
npm run generate
|
||||||
|
|
||||||
|
# Build for development (install, codegen, tsc)
|
||||||
|
npm run build:dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Only use Docker Compose for running tests, and only use `docker compose run test`
|
||||||
|
to run tests; don't try to run tests for individual files.
|
||||||
|
|
||||||
|
## Architecture Overview
|
||||||
|
|
||||||
|
Project Inter Server is a GraphQL-based backend for college transit tracking with real-time shuttle data, parking availability, and push notifications.
|
||||||
|
|
||||||
|
- InterchangeSystem: Central orchestrator for shuttles, parking, and notifications
|
||||||
|
- Use `InterchangeSystem.build()` in production
|
||||||
|
- Use `InterchangeSystem.buildForTesting()` in tests
|
||||||
|
|
||||||
|
- Repository Pattern (data access abstraction)
|
||||||
|
- Shuttle: `UnoptimizedInMemoryShuttleRepository`
|
||||||
|
- Parking: `InMemoryParkingRepository`
|
||||||
|
- Notifications: `RedisNotificationRepository` (prod) / `InMemoryNotificationRepository` (test)
|
||||||
|
|
||||||
|
- Data Loaders (external API integration)
|
||||||
|
- `ApiBasedShuttleRepositoryLoader` – Passio GO! API
|
||||||
|
- `ChapmanApiBasedParkingRepositoryLoader` – Parking data
|
||||||
|
- `TimedApiBasedRepositoryLoader` – Periodic refresh wrapper
|
||||||
|
|
||||||
|
- Notification System
|
||||||
|
- `ETANotificationScheduler` – Shuttle arrival notifications
|
||||||
|
- `AppleNotificationSender` – APNS integration
|
||||||
|
|
||||||
|
## GraphQL
|
||||||
|
- Schema definition: `schema.graphqls`
|
||||||
|
- Generated types: `src/generated/`
|
||||||
|
- Resolvers: `src/resolvers/`
|
||||||
|
- Resolver merge: `src/MergedResolvers.ts`
|
||||||
|
|
||||||
|
## Directory Structure
|
||||||
|
- `src/entities/` – Core business logic
|
||||||
|
- `src/repositories/` – Data access layer
|
||||||
|
- `src/loaders/` – External API integrations
|
||||||
|
- `src/notifications/` – Push notification system
|
||||||
|
- `src/resolvers/` – GraphQL resolvers and tests
|
||||||
|
- `testHelpers/` – Test utilities and mock data
|
||||||
|
|
||||||
|
## Docker Services
|
||||||
|
- `dev` – Development server with hot reload
|
||||||
|
- `test` – Unit/integration tests
|
||||||
|
- `redis` – Persistent Redis
|
||||||
|
- `redis-no-persistence` – Ephemeral Redis for tests
|
||||||
|
|
||||||
|
## Testing Patterns
|
||||||
|
- Prefer `buildForTesting()` to construct systems in tests.
|
||||||
|
- Mock external APIs using JSON snapshots under `testHelpers/jsonSnapshots`.
|
||||||
|
- Use in-memory repositories for speed where possible.
|
||||||
|
- When adding features that affect API output, add focused resolver tests in the corresponding `src/resolvers/__tests__` file.
|
||||||
|
- Separate unit tests from integration tests where practical to keep feedback fast and failures well-scoped.
|
||||||
|
|
||||||
|
## Development Guidelines
|
||||||
|
|
||||||
|
### General Guidelines
|
||||||
|
- Use test-driven development where possible. Write tests before implementation and run them before and after changes.
|
||||||
|
- Use Docker Compose for tests. Run `docker compose run test` so you can see full output.
|
||||||
|
|
||||||
|
### Git Workflow
|
||||||
|
- Name pull requests after their branch name.
|
||||||
|
|
||||||
|
### Code Style
|
||||||
|
- Prefer arrow functions, especially within classes.
|
||||||
|
- Keep changes minimal and focused; avoid unrelated refactors. Mention incidental issues separately.
|
||||||
|
- Respect existing interfaces and types; use non-destructive edits.
|
||||||
|
|
||||||
|
### Agent Tips
|
||||||
|
- Write or update tests alongside changes; validate with `docker compose run test`.
|
||||||
|
- When touching GraphQL resolvers, co-locate new tests in `src/resolvers/__tests__`.
|
||||||
|
|
||||||
|
## Multi-tenant Support
|
||||||
|
Currently supports Chapman University (Passio System ID: `263`). Each university system uses isolated repositories and configuration. New systems should be added via `InterchangeSystem` configuration and appropriate loaders.
|
||||||
|
|||||||
4
Caddyfile
Normal file
4
Caddyfile
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
interchange-api.bchen.dev {
|
||||||
|
reverse_proxy app:4000
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,7 +1,4 @@
|
|||||||
FROM node:22-alpine
|
FROM node:22-alpine
|
||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN npm run build
|
|
||||||
EXPOSE 4000
|
EXPOSE 4000
|
||||||
|
|
||||||
CMD ["npm", "run", "start"]
|
|
||||||
|
|||||||
@@ -19,8 +19,6 @@ services:
|
|||||||
build: .
|
build: .
|
||||||
command: npm run start
|
command: npm run start
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
|
||||||
- "4000:4000"
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- redis
|
- redis
|
||||||
environment:
|
environment:
|
||||||
@@ -36,6 +34,18 @@ services:
|
|||||||
- ./redis-stack.conf:/redis-stack.conf
|
- ./redis-stack.conf:/redis-stack.conf
|
||||||
command: redis-stack-server /redis-stack.conf
|
command: redis-stack-server /redis-stack.conf
|
||||||
|
|
||||||
|
caddy:
|
||||||
|
image: caddy:2-alpine
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
- "443:443/udp"
|
||||||
|
volumes:
|
||||||
|
- ./Caddyfile:/etc/caddy/Caddyfile
|
||||||
|
- caddy_data:/data
|
||||||
|
- caddy_config:/config
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
redis_data:
|
redis_data:
|
||||||
caddy_data:
|
caddy_data:
|
||||||
|
|||||||
1115
package-lock.json
generated
1115
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@
|
|||||||
"build:dev": "npm install --include=dev && npm run generate && tsc --project tsconfig.build.json",
|
"build:dev": "npm install --include=dev && npm run generate && tsc --project tsconfig.build.json",
|
||||||
"build": "npm install --include=dev && npm run generate && tsc --project tsconfig.build.json && npm prune --omit=dev",
|
"build": "npm install --include=dev && npm run generate && tsc --project tsconfig.build.json && npm prune --omit=dev",
|
||||||
"start:dev": "npm run build:dev && node ./dist/index.js",
|
"start:dev": "npm run build:dev && node ./dist/index.js",
|
||||||
"start": "node ./dist/index.js",
|
"start": "npm run build && node ./dist/index.js",
|
||||||
"generate": "graphql-codegen --config codegen.ts",
|
"generate": "graphql-codegen --config codegen.ts",
|
||||||
"test": "npm run build:dev && jest --runInBand"
|
"test": "npm run build:dev && jest --runInBand"
|
||||||
},
|
},
|
||||||
@@ -26,12 +26,12 @@
|
|||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@apollo/server": "^5.0.0",
|
"@apollo/server": "^4.11.2",
|
||||||
"@as-integrations/express5": "^1.1.2",
|
"@as-integrations/express5": "^1.1.2",
|
||||||
"express": "^5.1.0",
|
"express": "^5.1.0",
|
||||||
"express-rate-limit": "^8.0.1",
|
"express-rate-limit": "^8.0.1",
|
||||||
"express-slow-down": "^3.0.0",
|
"express-slow-down": "^3.0.0",
|
||||||
"graphql": "^16.11.0",
|
"graphql": "^16.10.0",
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
"redis": "^4.7.0"
|
"redis": "^4.7.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ scalar DateTime
|
|||||||
type System {
|
type System {
|
||||||
id: ID!
|
id: ID!
|
||||||
name: String!
|
name: String!
|
||||||
initialRegion: Region
|
|
||||||
routes: [Route!]
|
routes: [Route!]
|
||||||
route(id: ID): Route
|
route(id: ID): Route
|
||||||
stops: [Stop!]
|
stops: [Stop!]
|
||||||
@@ -17,11 +16,6 @@ type System {
|
|||||||
parkingSystem: ParkingSystem
|
parkingSystem: ParkingSystem
|
||||||
}
|
}
|
||||||
|
|
||||||
type Region {
|
|
||||||
topLeft: Coordinates!
|
|
||||||
bottomRight: Coordinates!
|
|
||||||
}
|
|
||||||
|
|
||||||
type ParkingSystem {
|
type ParkingSystem {
|
||||||
systemId: ID!
|
systemId: ID!
|
||||||
parkingStructures: [ParkingStructure!]
|
parkingStructures: [ParkingStructure!]
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import { InMemoryExternalSourceETARepository } from "../repositories/shuttle/eta
|
|||||||
import { ETAGetterRepository } from "../repositories/shuttle/eta/ETAGetterRepository";
|
import { ETAGetterRepository } from "../repositories/shuttle/eta/ETAGetterRepository";
|
||||||
import { InMemorySelfUpdatingETARepository } from "../repositories/shuttle/eta/InMemorySelfUpdatingETARepository";
|
import { InMemorySelfUpdatingETARepository } from "../repositories/shuttle/eta/InMemorySelfUpdatingETARepository";
|
||||||
import { BaseInMemoryETARepository } from "../repositories/shuttle/eta/BaseInMemoryETARepository";
|
import { BaseInMemoryETARepository } from "../repositories/shuttle/eta/BaseInMemoryETARepository";
|
||||||
import { IRegion } from "./SharedEntities";
|
|
||||||
|
|
||||||
export interface InterchangeSystemBuilderArguments {
|
export interface InterchangeSystemBuilderArguments {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -50,12 +49,6 @@ export interface InterchangeSystemBuilderArguments {
|
|||||||
* at a stop, in latitude/longitude degrees.
|
* at a stop, in latitude/longitude degrees.
|
||||||
*/
|
*/
|
||||||
shuttleStopArrivalDegreeDelta: number;
|
shuttleStopArrivalDegreeDelta: number;
|
||||||
|
|
||||||
/**
|
|
||||||
* The initial map region to display when the app first loads
|
|
||||||
* this system. Represents a center coordinate and span.
|
|
||||||
*/
|
|
||||||
initialRegion?: IRegion;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class InterchangeSystem {
|
export class InterchangeSystem {
|
||||||
@@ -69,7 +62,6 @@ export class InterchangeSystem {
|
|||||||
public notificationRepository: NotificationRepository,
|
public notificationRepository: NotificationRepository,
|
||||||
public parkingTimedDataLoader: TimedApiBasedRepositoryLoader | null,
|
public parkingTimedDataLoader: TimedApiBasedRepositoryLoader | null,
|
||||||
public parkingRepository: ParkingGetterSetterRepository | null,
|
public parkingRepository: ParkingGetterSetterRepository | null,
|
||||||
public initialRegion: IRegion | null,
|
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +96,6 @@ export class InterchangeSystem {
|
|||||||
notificationRepository,
|
notificationRepository,
|
||||||
timedParkingLoader,
|
timedParkingLoader,
|
||||||
parkingRepository,
|
parkingRepository,
|
||||||
args.initialRegion ?? null,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,7 +205,6 @@ export class InterchangeSystem {
|
|||||||
notificationRepository,
|
notificationRepository,
|
||||||
timedParkingLoader,
|
timedParkingLoader,
|
||||||
parkingRepository,
|
parkingRepository,
|
||||||
args.initialRegion ?? null,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,3 @@ export interface ICoordinates {
|
|||||||
longitude: number;
|
longitude: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IRegion {
|
|
||||||
topLeft: ICoordinates;
|
|
||||||
bottomRight: ICoordinates;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -25,10 +25,6 @@ const supportedSystems: InterchangeSystemBuilderArguments[] = [
|
|||||||
name: "Chapman University",
|
name: "Chapman University",
|
||||||
useSelfUpdatingEtas: true,
|
useSelfUpdatingEtas: true,
|
||||||
shuttleStopArrivalDegreeDelta: 0.001,
|
shuttleStopArrivalDegreeDelta: 0.001,
|
||||||
initialRegion: {
|
|
||||||
topLeft: { latitude: 33.85733, longitude: -117.89553 },
|
|
||||||
bottomRight: { latitude: 33.73970, longitude: -117.81878 },
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -83,14 +83,6 @@ export const SystemResolvers: Resolvers<ServerContext> = {
|
|||||||
const shuttles = await system.shuttleRepository.getShuttles();
|
const shuttles = await system.shuttleRepository.getShuttles();
|
||||||
return shuttles.slice().sort((a, b) => a.name.localeCompare(b.name));
|
return shuttles.slice().sort((a, b) => a.name.localeCompare(b.name));
|
||||||
},
|
},
|
||||||
initialRegion: async (parent, _args, contextValue, _info) => {
|
|
||||||
const system = contextValue.findSystemById(parent.id);
|
|
||||||
if (!system) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return system.initialRegion;
|
|
||||||
},
|
|
||||||
parkingSystem: async (parent, _args, contextValue, _info) => {
|
parkingSystem: async (parent, _args, contextValue, _info) => {
|
||||||
const system = contextValue.findSystemById(parent.id);
|
const system = contextValue.findSystemById(parent.id);
|
||||||
if (!system) {
|
if (!system) {
|
||||||
|
|||||||
@@ -35,37 +35,6 @@ describe("SystemResolvers", () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("initialRegion", () => {
|
|
||||||
const query = `
|
|
||||||
query GetSystemInitialRegion($systemId: ID!) {
|
|
||||||
system(id: $systemId) {
|
|
||||||
initialRegion {
|
|
||||||
topLeft {
|
|
||||||
latitude
|
|
||||||
longitude
|
|
||||||
}
|
|
||||||
bottomRight {
|
|
||||||
latitude
|
|
||||||
longitude
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
it("returns the initial region for the system", async () => {
|
|
||||||
const response = await getResponseFromQueryNeedingSystemId(query);
|
|
||||||
|
|
||||||
assert(response.body.kind === "single");
|
|
||||||
expect(response.body.singleResult.errors).toBeUndefined();
|
|
||||||
const initialRegion = (response.body.singleResult.data as any).system.initialRegion;
|
|
||||||
expect(initialRegion).toEqual({
|
|
||||||
topLeft: { latitude: 33.85733, longitude: -117.89553 },
|
|
||||||
bottomRight: { latitude: 33.7397, longitude: -117.81878 },
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("routes", () => {
|
describe("routes", () => {
|
||||||
const query = `
|
const query = `
|
||||||
query GetSystemRoutes($systemId: ID!) {
|
query GetSystemRoutes($systemId: ID!) {
|
||||||
|
|||||||
@@ -26,10 +26,6 @@ const systemInfoForTesting: InterchangeSystemBuilderArguments = {
|
|||||||
parkingSystemId: ChapmanApiBasedParkingRepositoryLoader.id,
|
parkingSystemId: ChapmanApiBasedParkingRepositoryLoader.id,
|
||||||
useSelfUpdatingEtas: false,
|
useSelfUpdatingEtas: false,
|
||||||
shuttleStopArrivalDegreeDelta: 0.001,
|
shuttleStopArrivalDegreeDelta: 0.001,
|
||||||
initialRegion: {
|
|
||||||
topLeft: { latitude: 33.85733, longitude: -117.89553 },
|
|
||||||
bottomRight: { latitude: 33.73970, longitude: -117.81878 },
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export function buildSystemForTesting() {
|
export function buildSystemForTesting() {
|
||||||
|
|||||||
Reference in New Issue
Block a user