feat(hunt): track walking distance via GPS, show live locations on map
Add foreground-only GPS distance tracking for hunts
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "public"."Hunt" ADD COLUMN "trackDistance" BOOLEAN NOT NULL DEFAULT false;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "public"."TrackPoint" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"lat" DECIMAL(10,8) NOT NULL,
|
||||
"lon" DECIMAL(10,8) NOT NULL,
|
||||
"accuracy" DOUBLE PRECISION,
|
||||
"recordedAt" TIMESTAMPTZ(3) NOT NULL,
|
||||
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"userId" INTEGER NOT NULL,
|
||||
"huntId" INTEGER NOT NULL,
|
||||
|
||||
CONSTRAINT "TrackPoint_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "public"."UserTrack" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"distanceMeters" INTEGER NOT NULL DEFAULT 0,
|
||||
"lastFixAt" TIMESTAMPTZ(3),
|
||||
"updatedAt" TIMESTAMPTZ(3) NOT NULL,
|
||||
"userId" INTEGER NOT NULL,
|
||||
"huntId" INTEGER NOT NULL,
|
||||
|
||||
CONSTRAINT "UserTrack_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "TrackPoint_userId_huntId_recordedAt_idx" ON "public"."TrackPoint"("userId", "huntId", "recordedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "UserTrack_userId_huntId_key" ON "public"."UserTrack"("userId", "huntId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."TrackPoint" ADD CONSTRAINT "TrackPoint_userId_fkey" FOREIGN KEY ("userId") REFERENCES "public"."User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."TrackPoint" ADD CONSTRAINT "TrackPoint_huntId_fkey" FOREIGN KEY ("huntId") REFERENCES "public"."Hunt"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."UserTrack" ADD CONSTRAINT "UserTrack_userId_fkey" FOREIGN KEY ("userId") REFERENCES "public"."User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."UserTrack" ADD CONSTRAINT "UserTrack_huntId_fkey" FOREIGN KEY ("huntId") REFERENCES "public"."Hunt"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -33,6 +33,9 @@ model User {
|
||||
reviews Review[]
|
||||
|
||||
uploadedFiles File[]
|
||||
|
||||
trackPoints TrackPoint[]
|
||||
userTracks UserTrack[]
|
||||
}
|
||||
|
||||
enum UserRole {
|
||||
@@ -80,6 +83,7 @@ model Hunt {
|
||||
revealQuests Boolean @default(false)
|
||||
revealAnswers Boolean @default(false)
|
||||
public Boolean @default(true)
|
||||
trackDistance Boolean @default(false)
|
||||
|
||||
creator User @relation(fields: [creatorId], references: [id], onUpdate: Cascade, onDelete: Cascade)
|
||||
creatorId Int
|
||||
@@ -98,6 +102,9 @@ model Hunt {
|
||||
|
||||
oldFiles File[] @relation("OldHuntFiles")
|
||||
|
||||
trackPoints TrackPoint[]
|
||||
userTracks UserTrack[]
|
||||
|
||||
@@index([creatorId])
|
||||
}
|
||||
|
||||
@@ -255,3 +262,41 @@ model Review {
|
||||
createdAt DateTime @default(now()) @db.Timestamptz(3)
|
||||
updatedAt DateTime @updatedAt @db.Timestamptz(3)
|
||||
}
|
||||
|
||||
/// A single raw GPS fix streamed by the client while tracking is active.
|
||||
/// All points are retained (for future map features); distance is derived
|
||||
/// server-side and stored on UserTrack.
|
||||
model TrackPoint {
|
||||
id Int @id @default(autoincrement())
|
||||
lat Decimal @db.Decimal(10, 8)
|
||||
lon Decimal @db.Decimal(10, 8)
|
||||
/// Reported accuracy in meters, if the device provided one.
|
||||
accuracy Float?
|
||||
recordedAt DateTime @db.Timestamptz(3)
|
||||
createdAt DateTime @default(now()) @db.Timestamptz(3)
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onUpdate: Cascade, onDelete: Cascade)
|
||||
userId Int
|
||||
|
||||
hunt Hunt @relation(fields: [huntId], references: [id], onUpdate: Cascade, onDelete: Cascade)
|
||||
huntId Int
|
||||
|
||||
@@index([userId, huntId, recordedAt])
|
||||
}
|
||||
|
||||
/// Per-user, per-hunt aggregate of the derived walking distance.
|
||||
/// Recomputed idempotently from all of the user's TrackPoints on each batch.
|
||||
model UserTrack {
|
||||
id Int @id @default(autoincrement())
|
||||
distanceMeters Int @default(0)
|
||||
lastFixAt DateTime? @db.Timestamptz(3)
|
||||
updatedAt DateTime @updatedAt @db.Timestamptz(3)
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onUpdate: Cascade, onDelete: Cascade)
|
||||
userId Int
|
||||
|
||||
hunt Hunt @relation(fields: [huntId], references: [id], onUpdate: Cascade, onDelete: Cascade)
|
||||
huntId Int
|
||||
|
||||
@@unique([userId, huntId])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user