refacto: Changing click cooldown to daily actions for users and teams
This commit is contained in:
@@ -13,6 +13,29 @@ export async function initUsersSchema() {
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
`);
|
||||
await initUserActionQuotaSchema();
|
||||
}
|
||||
|
||||
export async function initUserActionQuotaSchema() {
|
||||
await usersPool.query(`
|
||||
CREATE TABLE IF NOT EXISTS user_action_quota (
|
||||
user_id INTEGER PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
|
||||
actions_remaining INTEGER NOT NULL DEFAULT 0,
|
||||
quota_reset_at TIMESTAMPTZ NOT NULL DEFAULT '1970-01-01 00:00:00+00'
|
||||
);
|
||||
`);
|
||||
}
|
||||
|
||||
// ── Helpers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
/** Returns the next noon (12:00:00) UTC after the current moment. */
|
||||
export function nextNoonUtc() {
|
||||
const now = new Date();
|
||||
const noon = new Date(Date.UTC(
|
||||
now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), 12, 0, 0, 0
|
||||
));
|
||||
if (noon <= now) noon.setUTCDate(noon.getUTCDate() + 1);
|
||||
return noon;
|
||||
}
|
||||
|
||||
// ── Queries ───────────────────────────────────────────────────────────────────
|
||||
@@ -50,4 +73,42 @@ export async function getTeamPlayerCounts() {
|
||||
const result = { blue: 0, red: 0 };
|
||||
for (const row of rows) result[row.team] = row.count;
|
||||
return result;
|
||||
}
|
||||
|
||||
// ── User action quota ─────────────────────────────────────────────────────────
|
||||
|
||||
/** Returns the current quota row for a user, or null if it doesn't exist. */
|
||||
export async function getUserActionsRow(userId) {
|
||||
const { rows } = await usersPool.query(
|
||||
`SELECT actions_remaining, quota_reset_at FROM user_action_quota WHERE user_id = $1`,
|
||||
[userId]
|
||||
);
|
||||
return rows[0] ?? null;
|
||||
}
|
||||
|
||||
/** Insert or overwrite the quota row for a user. */
|
||||
export async function resetUserActions(userId, actionsRemaining, quotaResetAt) {
|
||||
await usersPool.query(
|
||||
`INSERT INTO user_action_quota (user_id, actions_remaining, quota_reset_at)
|
||||
VALUES ($1, $2, $3)
|
||||
ON CONFLICT (user_id) DO UPDATE
|
||||
SET actions_remaining = $2,
|
||||
quota_reset_at = $3`,
|
||||
[userId, actionsRemaining, quotaResetAt]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically decrements actions_remaining by 1 if > 0.
|
||||
* Returns the updated row (with new actions_remaining), or null if already 0.
|
||||
*/
|
||||
export async function decrementUserActions(userId) {
|
||||
const { rows } = await usersPool.query(
|
||||
`UPDATE user_action_quota
|
||||
SET actions_remaining = actions_remaining - 1
|
||||
WHERE user_id = $1 AND actions_remaining > 0
|
||||
RETURNING actions_remaining`,
|
||||
[userId]
|
||||
);
|
||||
return rows[0] ?? null;
|
||||
}
|
||||
Reference in New Issue
Block a user