Skip to content

Migration blocker: legacy PascalCase attribute names (ID/SK/GSI1PK) + Lambda KMSKeyARN config #85

@aron23

Description

@aron23

Context

I'm migrating an existing Go service (Autheory) from pay-theory/dynamorm to TableTheory.

The existing deployed DynamoDB table schema (created by CDK) uses PascalCase / acronym attribute names:

  • Primary key attributes: ID (PK), SK (SK)
  • GSI key attributes: GSI1PK, GSI1SK, GSI2PK, GSI2SK, GSI3PK, GSI3SK
  • Other attributes commonly referenced by GSIs: UserID, AccountID, Email, Username, Token, etc.

The migration goal is a drop-in ORM swap without a DynamoDB schema/data migration.

Problem 1: attribute-name validation blocks legacy schemas

TableTheory validates attribute names as camelCase by default (or snake_case when configured). This makes it impossible to represent attributes like ID, GSI1PK, etc even via attr: overrides, because attr:ID fails validation with errors like:

  • attribute name must be camelCase (got \"ID\")

This prevents registering models for existing tables unless we rename attributes or rebuild the table.

Desired behavior

Add an opt-in naming convention that accepts and preserves PascalCase attribute names.

One possible approach:

  • Allow a model-level marker tag: _ string \theorydb:"naming:pascalCase"``
  • When in pascalCase mode:
    • Default attribute names should be the Go field name unchanged (e.g. field ID => attribute ID, field GSI1PK => GSI1PK)
    • attr: overrides should be validated against pascalCase rules.
    • Validation pattern could be ^[A-Z][A-Za-z0-9]*$ (so acronyms like ID, TTL, GSI1PK are valid).

Alternative if you don't want a new convention:

  • Permit attr: overrides to bypass naming validation entirely (legacy escape hatch).

Problem 2: Lambda init doesn't provide KMSKeyARN for encrypted fields

TableTheory fails closed when any model includes theorydb:"encrypted" and session.Config.KMSKeyARN is empty (good behavior).

However, LambdaInit / NewLambdaOptimized currently construct a session.Config internally and do not expose a way to set KMSKeyARN.

This blocks any Lambda-based app that uses encrypted fields (common for user/session/provider tokens).

Desired behavior

Provide a supported way to configure KMSKeyARN in Lambda initialization, for example:

  • LambdaInitWithConfig(session.Config, models...)
  • or NewLambdaOptimizedWithConfig(session.Config)
  • or (simplest) have the Lambda init path read KMS_KEY_ARN (or a TableTheory-prefixed env var) into session.Config.KMSKeyARN.

Acceptance criteria

  • A model like:
type User struct {
    _ string `theorydb:"naming:pascalCase"`

    ID string `theorydb:"pk"`
    SK string `theorydb:"sk"`

    GSI1PK string `theorydb:"index:gsi1,pk"`
    GSI1SK string `theorydb:"index:gsi1,sk"`
}

registers successfully and uses DynamoDB attributes ID/SK/GSI1PK/GSI1SK (no implicit renaming).

  • In Lambda, if KMS_KEY_ARN is set, encrypted fields work without requiring a custom init path in every consuming service.

Happy to help with a PR or test cases if you'd like.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions