-- Local dev only. Mirrors the table definitions in sql/admin/001_init.sql -
-- keep the two in step - and seeds a ready-to-use dev account on top.
USE nachklang_admin;

CREATE TABLE IF NOT EXISTS `user` (
	`id`            VARCHAR(36)  NOT NULL,
	`name`          VARCHAR(255) NOT NULL,
	`email`         VARCHAR(255) NOT NULL,
	`emailVerified` TINYINT(1)   NOT NULL DEFAULT 0,
	`image`         TEXT         DEFAULT NULL,
	`createdAt`     DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP,
	`updatedAt`     DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP,
	-- Nachklang addition, declared through better-auth's additionalFields so
	-- the adapter knows about it. Disabling also revokes the user's sessions.
	`disabled`      TINYINT(1)   NOT NULL DEFAULT 0,
	PRIMARY KEY (`id`),
	UNIQUE KEY `user_email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS `session` (
	`id`        VARCHAR(36)  NOT NULL,
	`expiresAt` DATETIME     NOT NULL,
	`token`     VARCHAR(255) NOT NULL,
	`createdAt` DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP,
	`updatedAt` DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP,
	`ipAddress` VARCHAR(255) DEFAULT NULL,
	`userAgent` TEXT         DEFAULT NULL,
	`userId`    VARCHAR(36)  NOT NULL,
	PRIMARY KEY (`id`),
	UNIQUE KEY `session_token` (`token`),
	KEY `session_user` (`userId`),
	CONSTRAINT `session_user_fk` FOREIGN KEY (`userId`) REFERENCES `user` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS `account` (
	`id`                    VARCHAR(36)  NOT NULL,
	-- 1.7 addition: distinguishes a local credential account
	-- ("local:credential") from an OAuth issuer. Written by better-auth.
	`issuer`                VARCHAR(255) NOT NULL,
	`accountId`             VARCHAR(255) NOT NULL,
	`providerId`            VARCHAR(255) NOT NULL,
	`userId`                VARCHAR(36)  NOT NULL,
	`accessToken`           TEXT         DEFAULT NULL,
	`refreshToken`          TEXT         DEFAULT NULL,
	`idToken`               TEXT         DEFAULT NULL,
	`accessTokenExpiresAt`  DATETIME     DEFAULT NULL,
	`refreshTokenExpiresAt` DATETIME     DEFAULT NULL,
	`scope`                 TEXT         DEFAULT NULL,
	`password`              TEXT         DEFAULT NULL,
	`createdAt`             DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP,
	`updatedAt`             DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP,
	PRIMARY KEY (`id`),
	KEY `account_user` (`userId`),
	KEY `account_provider` (`providerId`, `accountId`),
	CONSTRAINT `account_user_fk` FOREIGN KEY (`userId`) REFERENCES `user` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- Password-reset and e-mail-verification tokens.
CREATE TABLE IF NOT EXISTS `verification` (
	`id`         VARCHAR(36)  NOT NULL,
	`identifier` VARCHAR(255) NOT NULL,
	`value`      TEXT         NOT NULL,
	`expiresAt`  DATETIME     NOT NULL,
	`createdAt`  DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP,
	`updatedAt`  DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP,
	PRIMARY KEY (`id`),
	KEY `verification_identifier` (`identifier`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS `passkey` (
	`id`           VARCHAR(36)  NOT NULL,
	`name`         VARCHAR(255) DEFAULT NULL,
	`publicKey`    TEXT         NOT NULL,
	`userId`       VARCHAR(36)  NOT NULL,
	`credentialID` VARCHAR(255) NOT NULL,
	`counter`      INT          NOT NULL DEFAULT 0,
	`deviceType`   VARCHAR(255) NOT NULL,
	`backedUp`     TINYINT(1)   NOT NULL DEFAULT 0,
	`transports`   VARCHAR(255) DEFAULT NULL,
	`createdAt`    DATETIME     DEFAULT CURRENT_TIMESTAMP,
	`aaguid`       VARCHAR(255) DEFAULT NULL,
	PRIMARY KEY (`id`),
	KEY `passkey_user` (`userId`),
	KEY `passkey_credential` (`credentialID`),
	CONSTRAINT `passkey_user_fk` FOREIGN KEY (`userId`) REFERENCES `user` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- Required by rateLimit.storage = 'database' in admin.auth.ts. Passenger may
-- run several API instances, and an in-memory limiter would give each of them
-- its own budget.
CREATE TABLE IF NOT EXISTS `rateLimit` (
	`id`          VARCHAR(36)  NOT NULL,
	`key`         VARCHAR(255) NOT NULL,
	`count`       INT          NOT NULL DEFAULT 0,
	-- Epoch milliseconds, not a DATETIME: better-auth stores a number here.
	`lastRequest` BIGINT       NOT NULL DEFAULT 0,
	PRIMARY KEY (`id`),
	UNIQUE KEY `rate_limit_key` (`key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- ---------------------------------------------------------------------------
-- Nachklang-owned tables
-- ---------------------------------------------------------------------------

-- Which apps a user may administer. `admin` is just another app: holding it is
-- what lets someone manage users and invitations. `role` is reserved for
-- per-app roles later and is 'admin' for every row today.
CREATE TABLE IF NOT EXISTS `user_app_permissions` (
	`user_id`    VARCHAR(36) NOT NULL,
	`app`        ENUM('calendar','feedback','tickets','admin') NOT NULL,
	`role`       VARCHAR(32) NOT NULL DEFAULT 'admin',
	`granted_by` VARCHAR(36) DEFAULT NULL,
	`granted_at` DATETIME    NOT NULL DEFAULT CURRENT_TIMESTAMP,
	PRIMARY KEY (`user_id`, `app`),
	CONSTRAINT `uap_user_fk` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- The only route to a new account: there is no public sign-up. Only the
-- SHA-256 of the token is stored, so a dump of this table hands out no access.
CREATE TABLE IF NOT EXISTS `invitations` (
	`id`          INT AUTO_INCREMENT PRIMARY KEY,
	`email`       VARCHAR(255) NOT NULL,
	`name`        VARCHAR(255) NOT NULL,
	`token_hash`  CHAR(64)     NOT NULL,
	`apps`        JSON         NOT NULL,
	`invited_by`  VARCHAR(36)  DEFAULT NULL,
	`created_at`  DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP,
	`expires_at`  DATETIME     NOT NULL,
	`accepted_at` DATETIME     DEFAULT NULL,
	`revoked_at`  DATETIME     DEFAULT NULL,
	UNIQUE KEY `inv_token_hash` (`token_hash`),
	KEY `inv_email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- ---------------------------------------------------------------------------
-- Dev seed: dev@nachklang.art / devpassword, with every app permission.
-- Local only - this account exists nowhere but in this container.
--
-- The password hash is better-auth's own scrypt format (salt:hash), produced
-- with better-auth 1.7.2's hashPassword(). Regenerate it if better-auth ever
-- changes that format; a hash it cannot parse shows up as "invalid password"
-- on an otherwise correct sign-in.
--
-- `issuer` must be exactly 'local:credential' - it is how better-auth 1.7
-- recognises a local password account when signing in.
-- ---------------------------------------------------------------------------
INSERT INTO `user` (`id`, `name`, `email`, `emailVerified`, `disabled`)
VALUES ('dev-user-0000-0000-0000-000000000001', 'Dev Admin', 'dev@nachklang.art', 1, 0);

INSERT INTO `account` (`id`, `issuer`, `accountId`, `providerId`, `userId`, `password`)
VALUES (
	'dev-acct-0000-0000-0000-000000000001',
	'local:credential',
	'dev-user-0000-0000-0000-000000000001',
	'credential',
	'dev-user-0000-0000-0000-000000000001',
	'e6a0485feb04b8fa64453db87badd8e1:85aaffd845e1e44fabc5be97d684c0f533845ed11088bd3f4d533ef277ead71da8372b5c6a72c7eae2d48e3270c50e2d13cffa4fcfb0b5cec456100b8f007ed2'
);

INSERT INTO `user_app_permissions` (`user_id`, `app`, `role`) VALUES
	('dev-user-0000-0000-0000-000000000001', 'calendar', 'admin'),
	('dev-user-0000-0000-0000-000000000001', 'feedback', 'admin'),
	('dev-user-0000-0000-0000-000000000001', 'tickets',  'admin'),
	('dev-user-0000-0000-0000-000000000001', 'admin',    'admin');
