Skip to content

Implement gist TTL expiry — auto-expire gists after configurable time-to-live #604

@BigBen-7

Description

@BigBen-7

Description

Gists are hyperlocal and time-sensitive by nature. This issue adds a TTL (time-to-live) system where gists automatically expire after a configurable period (default 24 hours). Expired gists should not be returned in GET /gists queries but should remain in the database for audit purposes.

Context

  • The gists table already has a created_at column (timestamptz)
  • We need to add an expires_at column (timestamptz)
  • The CreateGistDto should accept an optional ttlHours field (default: 24, max: 168 = 7 days)
  • All geospatial queries must filter out expired gists

Requirements

  • Add expires_at column to the Gist entity
  • Generate a TypeORM migration for the new column
  • Update CreateGistDto to accept optional ttlHours (number, min: 1, max: 168)
  • In GistsService.create(), calculate and set expires_at = created_at + ttlHours
  • Update GistRepository.findNearby() to add WHERE expires_at > NOW() to all queries
  • Update GistRepository.findByGistId() to also filter expired gists
  • Add a database index on expires_at for query performance
  • Add a scheduled CronJob (NestJS @Cron) that soft-deletes expired gists every hour

Files to Touch

  • Backend/src/gists/entities/gist.entity.ts — add expires_at column
  • Backend/src/gists/dto/create-gist.dto.ts — add optional ttlHours field
  • Backend/src/gists/gists.service.ts — set expires_at on create
  • Backend/src/gists/gist.repository.ts — filter expired gists in all queries
  • Backend/src/database/migrations/ — new migration for expires_at column
  • Backend/src/gists/gists.module.ts — register ScheduleModule if adding cron
  • Backend/package.json — add @nestjs/schedule if not present

Migration SQL (reference)

ALTER TABLE gists ADD COLUMN expires_at TIMESTAMPTZ NOT NULL DEFAULT NOW() + INTERVAL '24 hours';
CREATE INDEX idx_gists_expires_at ON gists (expires_at);

Acceptance Criteria

  • expires_at column exists in the database after migration
  • POST /gists with ttlHours: 2 sets expiry 2 hours from now
  • GET /gists does NOT return expired gists
  • GET /gists/:id returns 404 for expired gists
  • Cron job logs when it cleans up expired gists
  • Unit tests cover expiry filtering logic

Complexity: 300 points

Metadata

Metadata

Assignees

No one assigned

    Labels

    BackendBackend issues

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions