package db import ( "context" "time" "go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/mongo" "go.mongodb.org/mongo-driver/v2/mongo/options" ) // EnsureIndexes creates all required indexes. Safe to call on every startup // (mongo ignores duplicate index creation). func (c *Client) EnsureIndexes(ctx context.Context) error { if err := c.ensureUserIndexes(ctx); err != nil { return err } if err := c.ensureSessionIndexes(ctx); err != nil { return err } return c.ensureLaneIndexes(ctx) } func (c *Client) ensureLaneIndexes(ctx context.Context) error { _, err := c.Lanes().Indexes().CreateOne(ctx, mongo.IndexModel{ Keys: bson.D{{Key: "created_by", Value: 1}}, }) return err } func (c *Client) ensureUserIndexes(ctx context.Context) error { _, err := c.Users().Indexes().CreateOne(ctx, mongo.IndexModel{ Keys: bson.D{{Key: "username", Value: 1}}, Options: options.Index().SetUnique(true), }) return err } func (c *Client) ensureSessionIndexes(ctx context.Context) error { // Unique lookup index on the session token. if _, err := c.Sessions().Indexes().CreateOne(ctx, mongo.IndexModel{ Keys: bson.D{{Key: "token", Value: 1}}, Options: options.Index().SetUnique(true), }); err != nil { return err } // TTL index: MongoDB automatically deletes session documents after // expires_at has passed (checked roughly every 60 s by the reaper). expireAfter := int32(0) if _, err := c.Sessions().Indexes().CreateOne(ctx, mongo.IndexModel{ Keys: bson.D{{Key: "expires_at", Value: 1}}, Options: options.Index().SetExpireAfterSeconds(expireAfter), }); err != nil { return err } return nil } // SessionTTL is how long a session stays valid. const SessionTTL = 24 * time.Hour