Files
gamegroup2/backend/pb_migrations/1738717600_init.pb.js
T
congsh 4d1a53fc69 feat: initialize PocketBase backend with migrations
- Created backend directory structure
- Added .env configuration for PocketBase
- Added initial migration with users, groups, games, teamSessions, invitations collections
- Added docker-compose.yml for containerized deployment
- Added README.md with setup instructions

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 14:14:05 +08:00

782 lines
17 KiB
JavaScript

/// <reference path="../pb_data/types.d.ts" />
migrate((app) => {
// Users collection
app.deleteCollection("users");
app.createCollection("users", {
id: "users",
name: "users",
type: "auth",
fields: [
{
id: "new_aQr3td8dJl",
name: "username",
type: "text",
system: false,
required: true,
unique: true,
options: {
min: 3,
max: 20,
pattern: "^[a-zA-Z0-9_]+$",
}
},
{
id: "new_Jx4zWq9kLm",
name: "displayName",
type: "text",
system: false,
required: true,
unique: false,
options: {
min: null,
max: 50,
pattern: "",
}
},
{
id: "new_Xp7vR2sT4u",
name: "avatar",
type: "url",
system: false,
required: false,
unique: false,
options: {
exceptDomains: null,
onlyDomains: null,
}
},
{
id: "new_Nh8gD3fF6g",
name: "bio",
type: "text",
system: false,
required: false,
unique: false,
options: {
min: null,
max: 500,
pattern: "",
}
},
{
id: "new_Vc5bH8kJ7o",
name: "region",
type: "select",
system: false,
required: true,
unique: false,
options: {
maxSelect: 1,
values: [
"cn",
"us",
"eu",
"asia",
"other"
],
}
},
{
id: "new_Tf6rK9mP8q",
name: "preferences",
type: "json",
system: false,
required: false,
unique: false,
options: {
maxSize: 10000,
}
},
{
id: "new_Dg7hL0nR9s",
name: "stats",
type: "json",
system: false,
required: false,
unique: false,
options: {
maxSize: 10000,
}
},
{
id: "new_Wm8jO1pS0t",
name: "isActive",
type: "bool",
system: false,
required: false,
unique: false,
options: {}
},
{
id: "new_Yn9kQ2qT1u",
name: "lastSeen",
type: "date",
system: false,
required: false,
unique: false,
options: {
min: "",
max: "",
}
},
],
indexes: [
"create index users_username_idx on users (username)",
"create index users_region_idx on users (region)",
"create index users_isActive_idx on users (isActive)",
],
listRule: "id = @request.auth.id",
viewRule: "id = @request.auth.id",
createRule: null,
updateRule: "id = @request.auth.id",
deleteRule: "id = @request.auth.id",
options: {
allowEmailAuth: true,
allowOAuth2Auth: false,
allowUsernameAuth: false,
exceptEmailDomains: null,
manageRule: null,
minPasswordLength: 8,
onlyEmailDomains: null,
requireEmail: false,
}
});
// Games collection
app.deleteCollection("games");
app.createCollection("games", {
id: "games",
name: "games",
type: "base",
fields: [
{
id: "new_Zp3wT8sV5x",
name: "name",
type: "text",
system: false,
required: true,
unique: true,
options: {
min: 1,
max: 100,
pattern: "",
}
},
{
id: "new_Bq4xU9tW6y",
name: "nameEn",
type: "text",
system: false,
required: false,
unique: false,
options: {
min: null,
max: 100,
pattern: "",
}
},
{
id: "new_Cr5yV0uX7z",
name: "cover",
type: "url",
system: false,
required: false,
unique: false,
options: {
exceptDomains: null,
onlyDomains: null,
}
},
{
id: "new_Ds6zW1vY8a",
name: "description",
type: "editor",
system: false,
required: false,
unique: false,
options: {
convertUrls: false,
}
},
{
id: "new_Et7aX2wZ9b",
name: "type",
type: "select",
system: false,
required: true,
unique: false,
options: {
maxSelect: 1,
values: [
"fps",
"moba",
"rpg",
"strategy",
"racing",
"sports",
"casual",
"other"
],
}
},
{
id: "new_Fu8bY3xA0c",
name: "platform",
type: "select",
system: false,
required: true,
unique: false,
options: {
maxSelect: 1,
values: [
"pc",
"mobile",
"console",
"crossplay"
],
}
},
{
id: "new_Gv9cZ4yB1d",
name: "maxTeamSize",
type: "number",
system: false,
required: true,
unique: false,
options: {
min: 2,
max: 100,
noDecimal: true,
}
},
{
id: "new_Hw0dA5zC2e",
name: "tags",
type: "json",
system: false,
required: false,
unique: false,
options: {
maxSize: 5000,
}
},
{
id: "new_Ix1eB6aD3f",
name: "isActive",
type: "bool",
system: false,
required: false,
unique: false,
options: {}
},
],
indexes: [
"create index games_name_idx on games (name)",
"create index games_type_idx on games (type)",
"create index games_platform_idx on games (platform)",
"create index games_isActive_idx on games (isActive)",
],
listRule: "",
viewRule: "",
createRule: null,
updateRule: null,
deleteRule: null,
options: {
allowEmailAuth: false,
allowOAuth2Auth: false,
allowUsernameAuth: false,
exceptEmailDomains: null,
manageRule: null,
onlyEmailDomains: null,
requireEmail: false,
}
});
// Groups collection
app.deleteCollection("groups");
app.createCollection("groups", {
id: "groups",
name: "groups",
type: "base",
fields: [
{
id: "new_Jy2fC7bE4g",
name: "name",
type: "text",
system: false,
required: true,
unique: false,
options: {
min: 3,
max: 50,
pattern: "",
}
},
{
id: "new_Kz3gD8cF5h",
name: "description",
type: "text",
system: false,
required: false,
unique: false,
options: {
min: null,
max: 500,
pattern: "",
}
},
{
id: "new_La4hE9dG6i",
name: "avatar",
type: "url",
system: false,
required: false,
unique: false,
options: {
exceptDomains: null,
onlyDomains: null,
}
},
{
id: "new_Mb5iF0eH7j",
name: "owner",
type: "relation",
system: false,
required: true,
unique: false,
options: {
collectionId: "users",
cascadeDelete: true,
minSelect: null,
maxSelect: 1,
displayFields: [
"username",
"displayName"
],
}
},
{
id: "new_Nc6jG1fI8k",
name: "game",
type: "relation",
system: false,
required: true,
unique: false,
options: {
collectionId: "games",
cascadeDelete: false,
minSelect: null,
maxSelect: 1,
displayFields: [
"name"
],
}
},
{
id: "new_Od7kH2gJ9l",
name: "members",
type: "relation",
system: false,
required: false,
unique: false,
options: {
collectionId: "users",
cascadeDelete: false,
minSelect: null,
maxSelect: null,
displayFields: [
"username",
"displayName"
],
}
},
{
id: "new_Pe8lI3hK0m",
name: "maxMembers",
type: "number",
system: false,
required: true,
unique: false,
options: {
min: 2,
max: 100,
noDecimal: true,
}
},
{
id: "new_Qf9mJ4iL1n",
name: "status",
type: "select",
system: false,
required: true,
unique: false,
options: {
maxSelect: 1,
values: [
"recruiting",
"full",
"inactive"
],
}
},
{
id: "new_Rg0nK5jM2o",
name: "tags",
type: "json",
system: false,
required: false,
unique: false,
options: {
maxSize: 5000,
}
},
{
id: "new_Sh1oL6kN3p",
name: "requirements",
type: "json",
system: false,
required: false,
unique: false,
options: {
maxSize: 10000,
}
},
{
id: "new_Ti2pM7lO4q",
name: "stats",
type: "json",
system: false,
required: false,
unique: false,
options: {
maxSize: 10000,
}
},
],
indexes: [
"create index groups_name_idx on groups (name)",
"create index groups_owner_idx on groups (owner)",
"create index groups_game_idx on groups (game)",
"create index groups_status_idx on groups (status)",
],
listRule: "",
viewRule: "",
createRule: "@request.auth.id != \"\"",
updateRule: "owner = @request.auth.id",
deleteRule: "owner = @request.auth.id",
options: {
allowEmailAuth: false,
allowOAuth2Auth: false,
allowUsernameAuth: false,
exceptEmailDomains: null,
manageRule: null,
onlyEmailDomains: null,
requireEmail: false,
}
});
// Team Sessions collection
app.deleteCollection("teamSessions");
app.createCollection("teamSessions", {
id: "teamSessions",
name: "teamSessions",
type: "base",
fields: [
{
id: "new_Uj3qN8mP5r",
name: "group",
type: "relation",
system: false,
required: true,
unique: false,
options: {
collectionId: "groups",
cascadeDelete: true,
minSelect: null,
maxSelect: 1,
displayFields: [
"name"
],
}
},
{
id: "new_Vk4rO9nQ6s",
name: "host",
type: "relation",
system: false,
required: true,
unique: false,
options: {
collectionId: "users",
cascadeDelete: false,
minSelect: null,
maxSelect: 1,
displayFields: [
"username",
"displayName"
],
}
},
{
id: "new_Wl5sP0oR7t",
name: "participants",
type: "relation",
system: false,
required: false,
unique: false,
options: {
collectionId: "users",
cascadeDelete: false,
minSelect: null,
maxSelect: null,
displayFields: [
"username",
"displayName"
],
}
},
{
id: "new_Xm6tQ1pS8u",
name: "status",
type: "select",
system: false,
required: true,
unique: false,
options: {
maxSelect: 1,
values: [
"waiting",
"playing",
"completed",
"cancelled"
],
}
},
{
id: "new_Yn7uR2qT9v",
name: "voiceChat",
type: "bool",
system: false,
required: false,
unique: false,
options: {}
},
{
id: "new_Zo8vS3rU0w",
name: "roomInfo",
type: "json",
system: false,
required: false,
unique: false,
options: {
maxSize: 10000,
}
},
{
id: "new_Ap9wT4sV1x",
name: "notes",
type: "text",
system: false,
required: false,
unique: false,
options: {
min: null,
max: 1000,
pattern: "",
}
},
{
id: "new_Bq0xU5tW2y",
name: "scheduledAt",
type: "date",
system: false,
required: false,
unique: false,
options: {
min: "",
max: "",
}
},
{
id: "new_Cr1yV6uX3z",
name: "startedAt",
type: "date",
system: false,
required: false,
unique: false,
options: {
min: "",
max: "",
}
},
{
id: "new_Ds2zW7vY4a",
name: "endedAt",
type: "date",
system: false,
required: false,
unique: false,
options: {
min: "",
max: "",
}
},
],
indexes: [
"create index teamSessions_group_idx on teamSessions (group)",
"create index teamSessions_host_idx on teamSessions (host)",
"create index teamSessions_status_idx on teamSessions (status)",
"create index teamSessions_scheduledAt_idx on teamSessions (scheduledAt)",
],
listRule: "group.owner = @request.auth.id || group.members.id = @request.auth.id",
viewRule: "group.owner = @request.auth.id || group.members.id = @request.auth.id",
createRule: "@request.auth.id != \"\"",
updateRule: "group.owner = @request.auth.id",
deleteRule: "group.owner = @request.auth.id",
options: {
allowEmailAuth: false,
allowOAuth2Auth: false,
allowUsernameAuth: false,
exceptEmailDomains: null,
manageRule: null,
onlyEmailDomains: null,
requireEmail: false,
}
});
// Invitations collection
app.deleteCollection("invitations");
app.createCollection("invitations", {
id: "invitations",
name: "invitations",
type: "base",
fields: [
{
id: "new_Et3yZ8wB5c",
name: "group",
type: "relation",
system: false,
required: true,
unique: false,
options: {
collectionId: "groups",
cascadeDelete: true,
minSelect: null,
maxSelect: 1,
displayFields: [
"name"
],
}
},
{
id: "new_Fu4zA9xC6d",
name: "sender",
type: "relation",
system: false,
required: true,
unique: false,
options: {
collectionId: "users",
cascadeDelete: false,
minSelect: null,
maxSelect: 1,
displayFields: [
"username",
"displayName"
],
}
},
{
id: "new_Gv5aB0yD7e",
name: "recipient",
type: "relation",
system: false,
required: true,
unique: false,
options: {
collectionId: "users",
cascadeDelete: false,
minSelect: null,
maxSelect: 1,
displayFields: [
"username",
"displayName"
],
}
},
{
id: "new_Hw6bC1zE8f",
name: "status",
type: "select",
system: false,
required: true,
unique: false,
options: {
maxSelect: 1,
values: [
"pending",
"accepted",
"rejected",
"cancelled"
],
}
},
{
id: "new_Ix7cD2aF9g",
name: "message",
type: "text",
system: false,
required: false,
unique: false,
options: {
min: null,
max: 500,
pattern: "",
}
},
{
id: "new_Jy8dE3bG0h",
name: "respondedAt",
type: "date",
system: false,
required: false,
unique: false,
options: {
min: "",
max: "",
}
},
],
indexes: [
"create index invitations_group_idx on invitations (group)",
"create index invitations_sender_idx on invitations (sender)",
"create index invitations_recipient_idx on invitations (recipient)",
"create index invitations_status_idx on invitations (status)",
"create unique index invitations_unique_pending on invitations (group, recipient) where status = 'pending'",
],
listRule: "sender = @request.auth.id || recipient = @request.auth.id || group.owner = @request.auth.id",
viewRule: "sender = @request.auth.id || recipient = @request.auth.id || group.owner = @request.auth.id",
createRule: "group.owner = @request.auth.id",
updateRule: "recipient = @request.auth.id",
deleteRule: "sender = @request.auth.id || group.owner = @request.auth.id",
options: {
allowEmailAuth: false,
allowOAuth2Auth: false,
allowUsernameAuth: false,
exceptEmailDomains: null,
manageRule: null,
onlyEmailDomains: null,
requireEmail: false,
}
});
}, (app) => {
// Rollback
app.deleteCollection("invitations");
app.deleteCollection("teamSessions");
app.deleteCollection("groups");
app.deleteCollection("games");
app.deleteCollection("users");
});