Skip to content

Enable Sponsor CRM TTL on expiresAt #163

Description

@alexeygrigorev

Enable Sponsor CRM TTL on expiresAt

Status: blocked — Tester/PM accepted and committed locally as b19cc3c; unpushed and unshipped behind the coordinated #166 rollout
Tags: bug, infra, data, P1
Depends on: #166 rollout sequencing for publication; source implementation is complete
Blocks: None
Next owner: #166 orchestrator and credentialed operator for the ordered GitHub Actions OIDC rollout; On-Call after the containing phase deploys
Resume condition: accepted aws-infra prerequisite bc27d07 is applied and #166 repaired Phase A 55b2d00 has production PASS evidence; then advance only repaired Phase B f32af76, which contains this exact commit, and retain this issue until On-Call proves same-table TTL ENABLED on expiresAt

Scope

Enable DynamoDB TTL for the existing CloudFormation-owned Sponsor CRM table by changing only the DataOpsSponsorCrmTable resource in infra/template.full.yaml:

TimeToLiveSpecification:
  Enabled: true
  AttributeName: expiresAt

Update the existing Sponsor table infrastructure test in tests/infra/test_template.py, which intentionally asserts that TTL is absent, so it instead asserts this exact enabled TTL contract. Preserve the table's physical identity and every other declared property, including its name, billing mode, encryption, point-in-time recovery, partition/sort keys, attribute definitions, four GSIs, stream configuration, DeletionPolicy, and UpdateReplacePolicy.

The sanitized production preflight recorded on 2026-08-13 establishes that DataOpsSponsorCrmTable is CloudFormation-owned and ACTIVE, all four expected GSIs are ACTIVE, the last stack update was 2026-08-11T23:26:34Z, DynamoDB TTL is DISABLED, and the prior cooldown has elapsed.

Ship through the normal main GitHub Actions OIDC deployment only. On-Call owns terminal CloudFormation and DynamoDB verification after the approved change reaches main.

Acceptance Criteria

  • DataOpsSponsorCrmTable alone gains TimeToLiveSpecification with Enabled: true and AttributeName: expiresAt in infra/template.full.yaml.
  • The existing Sponsor infrastructure test no longer asserts intentional TTL absence and instead asserts the exact enabled expiresAt TTL contract.
  • The Sponsor table retains the same TableName, BillingMode, SSESpecification, point-in-time recovery, AttributeDefinitions, KeySchema, four named GSIs and their key schemas/projections, StreamSpecification, DeletionPolicy, and UpdateReplacePolicy.
  • SAM/CloudFormation template validation succeeds.
  • The focused Sponsor table test and the complete tests/infra suite pass.
  • The approved commit is deployed only by the normal main GitHub Actions workflow using OIDC; no manual application deployment is used.
  • On-Call records a terminal successful deploy with the CloudFormation stack in UPDATE_COMPLETE.
  • On-Call verifies the same physical Sponsor CRM table remains ACTIVE, all four expected GSIs remain ACTIVE, its stream remains enabled with NEW_AND_OLD_IMAGES, and DynamoDB reports TTL ENABLED on expiresAt.
  • Verification evidence is sanitized and contains no item data, secrets, or credentials.

Test Scenarios

Scenario: Exact template change

Given: DataOpsSponsorCrmTable is the existing retained Sponsor CRM table and currently has no TTL declaration.

When: the engineer adds the TTL specification.

Then: that resource contains exactly Enabled: true and AttributeName: expiresAt, while no unrelated resource or Sponsor table property changes.

Scenario: Infrastructure regression coverage

Given: test_sponsor_communication_table_indexes_ttl_stream_and_default_off_contract currently documents the temporary absence of TTL.

When: the test is updated and the infrastructure suite runs.

Then: it asserts enabled TTL on expiresAt as well as the existing retention, encryption, recovery, stream, GSI, and default-off contracts, and all infra tests pass.

Scenario: Template validity

Given: the edited application template.

When: sam validate --lint --template-file infra/template.full.yaml runs.

Then: validation exits successfully without CloudFormation or SAM errors.

Scenario: Normal OIDC deployment

Given: Tester and PM have accepted the implementation and the approved commit reaches main.

When: the normal DataOps deployment workflow runs.

Then: it assumes the existing GitHub Actions role via OIDC and reaches terminal success without a manual application deployment.

Scenario: Production TTL enabled in place

Given: the production table and four GSIs were ACTIVE before deployment and TTL was DISABLED.

When: On-Call performs sanitized terminal verification after CloudFormation reaches UPDATE_COMPLETE.

Then: the same physical table is ACTIVE; GSI-Communication, GSI-SponsorSendDue, GSI-SponsorSendLookup, and GSI-SponsorBookingCommunication are all ACTIVE; the stream is still NEW_AND_OLD_IMAGES; and describe-time-to-live reports TTLStatus: ENABLED with AttributeName: expiresAt.

Required Verification

  • Focused: uv run --with pytest python -m pytest tests/infra/test_template.py -k sponsor_communication_table_indexes_ttl_stream_and_default_off_contract
  • Full infrastructure: uv run --with pytest python -m pytest tests/infra
  • Template: sam validate --lint --template-file infra/template.full.yaml
  • Review the diff to prove only the Sponsor TTL declaration and its intentional regression assertion changed.
  • After push, On-Call records the normal workflow run URL/conclusion, terminal CloudFormation status, and sanitized describe-table / describe-time-to-live results.

Out of Scope

  • Migration, import, reset, rollback, reconciliation, or cleanup frameworks.
  • Reading, changing, exporting, backfilling, or otherwise operating on Sponsor CRM item data.
  • Replacing, renaming, recreating, or manually updating the DynamoDB table.
  • Changing any key, index, stream, retention, encryption, recovery, billing, or physical-name property.
  • Adding application code, migration-only API routes, compatibility paths, feature flags, or ongoing migration tests.
  • Editing or deploying from aws-infra; this is the application-stack exception that remains in infra/template.full.yaml.
  • A manual SAM/CloudFormation application deploy.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1ImportantbugSomething is brokendataData model, migration, storageinfraDeployment and infrastructure

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions