mirror of
https://github.com/pikami/scrummie-poker.git
synced 2025-12-19 17:12:17 +00:00
Implement session invites
This commit is contained in:
148
functions/EstimationSessionInvite/.gitignore
vendored
Normal file
148
functions/EstimationSessionInvite/.gitignore
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
### Node ###
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variable files
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# vuepress v2.x temp and cache directory
|
||||
.temp
|
||||
|
||||
# Docusaurus cache and generated files
|
||||
.docusaurus
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
### Node Patch ###
|
||||
# Serverless Webpack directories
|
||||
.webpack/
|
||||
|
||||
# Optional stylelint cache
|
||||
|
||||
# SvelteKit build / generate output
|
||||
.svelte-kit
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/node
|
||||
|
||||
# OS
|
||||
## Mac
|
||||
.DS_Store
|
||||
|
||||
# Directory used by Appwrite CLI for local development
|
||||
.appwrite
|
||||
39
functions/EstimationSessionInvite/README.md
Normal file
39
functions/EstimationSessionInvite/README.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Estimation Session Invite Function
|
||||
|
||||
This function allows other users to join an existing estimation session by providing it's Id.
|
||||
|
||||
## Usage
|
||||
|
||||
### GET /?action=get-info&estimationId=[session-id]
|
||||
|
||||
- Gets session's information by id
|
||||
|
||||
**Response**
|
||||
|
||||
Sample `200` Response:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "session-id",
|
||||
"name": "session name"
|
||||
}
|
||||
```
|
||||
|
||||
### GET /?action=join&estimationId=[session-id]
|
||||
|
||||
- Joins session by id
|
||||
|
||||
**Response**
|
||||
|
||||
Sample `200` Response:
|
||||
|
||||
```json
|
||||
{
|
||||
"message": "Estimation session joined"
|
||||
}
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
- APPWRITE_DATABASE_ID - Database Id
|
||||
- APPWRITE_ESTIMATION_SESSION_COLLECTION_ID - Sessions collection Id
|
||||
BIN
functions/EstimationSessionInvite/bun.lockb
Executable file
BIN
functions/EstimationSessionInvite/bun.lockb
Executable file
Binary file not shown.
10
functions/EstimationSessionInvite/env.d.ts
vendored
Normal file
10
functions/EstimationSessionInvite/env.d.ts
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
declare module 'bun' {
|
||||
interface Env {
|
||||
APPWRITE_FUNCTION_API_ENDPOINT: string;
|
||||
APPWRITE_FUNCTION_PROJECT_ID: string;
|
||||
APPWRITE_DATABASE_ID: string;
|
||||
APPWRITE_ESTIMATION_SESSION_COLLECTION_ID: string;
|
||||
}
|
||||
}
|
||||
|
||||
export {};
|
||||
88
functions/EstimationSessionInvite/package-lock.json
generated
Normal file
88
functions/EstimationSessionInvite/package-lock.json
generated
Normal file
@@ -0,0 +1,88 @@
|
||||
{
|
||||
"name": "estimation-session-invite",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "estimation-session-invite",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"node-appwrite": "^14.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.1.11",
|
||||
"prettier": "^3.3.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/bun": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/bun/-/bun-1.1.11.tgz",
|
||||
"integrity": "sha512-0N7D/H/8sbf9JMkaG5F3+I/cB4TlhKTkO9EskEWP8XDr8aVcDe4EywSnU4cnyZy6tar1dq70NeFNkqMEUigthw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"bun-types": "1.1.30"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.12.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.14.tgz",
|
||||
"integrity": "sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/ws": {
|
||||
"version": "8.5.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz",
|
||||
"integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/bun-types": {
|
||||
"version": "1.1.30",
|
||||
"resolved": "https://registry.npmjs.org/bun-types/-/bun-types-1.1.30.tgz",
|
||||
"integrity": "sha512-mGh7NLisOXskBU62DxLS+/nwmLlCYHYAkCzdo4DZ9+fzrpP41hAdOqaN4DO6tQfenHb4pYb0/shw29k4/6I2yQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "~20.12.8",
|
||||
"@types/ws": "~8.5.10"
|
||||
}
|
||||
},
|
||||
"node_modules/node-appwrite": {
|
||||
"version": "14.1.0",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"node-fetch-native-with-agent": "1.7.2"
|
||||
}
|
||||
},
|
||||
"node_modules/node-fetch-native-with-agent": {
|
||||
"version": "1.7.2",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz",
|
||||
"integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
18
functions/EstimationSessionInvite/package.json
Normal file
18
functions/EstimationSessionInvite/package.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "estimation-session-invite",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "src/main.ts",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"format": "prettier --write ."
|
||||
},
|
||||
"dependencies": {
|
||||
"node-appwrite": "^14.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.1.11",
|
||||
"bun-types": "^1.1.30",
|
||||
"prettier": "^3.3.3"
|
||||
}
|
||||
}
|
||||
49
functions/EstimationSessionInvite/src/definitions.d.mts
Normal file
49
functions/EstimationSessionInvite/src/definitions.d.mts
Normal file
@@ -0,0 +1,49 @@
|
||||
declare type AppwriteRequest = {
|
||||
bodyRaw: string;
|
||||
body: Object;
|
||||
headers: Object;
|
||||
scheme: string;
|
||||
method: string;
|
||||
url: string;
|
||||
host: string;
|
||||
port: number;
|
||||
path: string;
|
||||
queryString: string;
|
||||
query: Object;
|
||||
};
|
||||
|
||||
declare type AppwriteSendReturn = {
|
||||
body: any;
|
||||
statusCode: number;
|
||||
headers: Object;
|
||||
};
|
||||
|
||||
declare type AppwriteResponse = {
|
||||
empty: () => AppwriteSendReturn;
|
||||
json: (obj: any, statusCode?: number, headers?: Object) => AppwriteSendReturn;
|
||||
text: (text: string) => AppwriteSendReturn;
|
||||
redirect: (
|
||||
url: string,
|
||||
statusCode?: number,
|
||||
headers?: Object,
|
||||
) => AppwriteSendReturn;
|
||||
send: (
|
||||
body: any,
|
||||
statusCode?: number,
|
||||
headers?: Object,
|
||||
) => AppwriteSendReturn;
|
||||
};
|
||||
|
||||
declare type AppwriteRuntimeContext = {
|
||||
req: AppwriteRequest;
|
||||
res: AppwriteResponse;
|
||||
log: (message: any) => void;
|
||||
error: (message: any) => void;
|
||||
};
|
||||
|
||||
export {
|
||||
AppwriteRequest,
|
||||
AppwriteSendReturn,
|
||||
AppwriteResponse,
|
||||
AppwriteRuntimeContext,
|
||||
};
|
||||
148
functions/EstimationSessionInvite/src/main.ts
Normal file
148
functions/EstimationSessionInvite/src/main.ts
Normal file
@@ -0,0 +1,148 @@
|
||||
import { Client, Databases } from 'node-appwrite';
|
||||
import { AppwriteRuntimeContext, AppwriteSendReturn } from './definitions.mjs';
|
||||
|
||||
const joinSession = async ({
|
||||
client,
|
||||
estimationId,
|
||||
userId,
|
||||
ctx: { error, res },
|
||||
}: {
|
||||
client: Client;
|
||||
estimationId: string;
|
||||
userId: string;
|
||||
ctx: AppwriteRuntimeContext;
|
||||
}): Promise<AppwriteSendReturn> => {
|
||||
const databases = new Databases(client);
|
||||
|
||||
let estimation;
|
||||
try {
|
||||
estimation = await databases.getDocument(
|
||||
Bun.env.APPWRITE_DATABASE_ID,
|
||||
Bun.env.APPWRITE_ESTIMATION_SESSION_COLLECTION_ID,
|
||||
estimationId,
|
||||
);
|
||||
} catch (e) {
|
||||
error({ e });
|
||||
return res.json(
|
||||
{
|
||||
message: 'Estimation with this id does not exist',
|
||||
},
|
||||
400,
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const permissions: string[] = estimation['$permissions'];
|
||||
permissions.push(`read("user:${userId}")`);
|
||||
permissions.push(`update("user:${userId}")`);
|
||||
|
||||
await databases.updateDocument(
|
||||
Bun.env.APPWRITE_DATABASE_ID,
|
||||
Bun.env.APPWRITE_ESTIMATION_SESSION_COLLECTION_ID,
|
||||
estimationId,
|
||||
{},
|
||||
permissions,
|
||||
);
|
||||
|
||||
return res.json({
|
||||
message: 'Estimation session joined',
|
||||
});
|
||||
} catch (e) {
|
||||
error({ e });
|
||||
return res.json(
|
||||
{
|
||||
message: 'Failed to join estimation session',
|
||||
},
|
||||
500,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const getSessionInfo = async ({
|
||||
client,
|
||||
estimationId,
|
||||
ctx: { log, res },
|
||||
}: {
|
||||
client: Client;
|
||||
estimationId: string;
|
||||
ctx: AppwriteRuntimeContext;
|
||||
}): Promise<AppwriteSendReturn> => {
|
||||
const databases = new Databases(client);
|
||||
|
||||
try {
|
||||
const estimation = await databases.getDocument(
|
||||
Bun.env.APPWRITE_DATABASE_ID,
|
||||
Bun.env.APPWRITE_ESTIMATION_SESSION_COLLECTION_ID,
|
||||
estimationId,
|
||||
);
|
||||
|
||||
return res.json({
|
||||
result: {
|
||||
id: estimation.$id,
|
||||
name: estimation.name,
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
console.log({ e });
|
||||
log({ e });
|
||||
return res.json(
|
||||
{
|
||||
message: 'Estimation with this id does not exist',
|
||||
},
|
||||
400,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default async (ctx: AppwriteRuntimeContext) => {
|
||||
const { req, res } = ctx;
|
||||
const userId = req.headers['x-appwrite-user-id'];
|
||||
if (!userId) {
|
||||
return res.json(
|
||||
{
|
||||
message: 'Unauthorized',
|
||||
},
|
||||
401,
|
||||
);
|
||||
}
|
||||
|
||||
const action = req.query['action'];
|
||||
const estimationId = req.query['estimationId'];
|
||||
if (!action || !estimationId) {
|
||||
return res.json(
|
||||
{
|
||||
message: 'Bad request',
|
||||
},
|
||||
400,
|
||||
);
|
||||
}
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint(Bun.env.APPWRITE_FUNCTION_API_ENDPOINT)
|
||||
.setProject(Bun.env.APPWRITE_FUNCTION_PROJECT_ID)
|
||||
.setKey(req.headers['x-appwrite-key'] ?? '');
|
||||
|
||||
if (action === 'get-info') {
|
||||
return await getSessionInfo({
|
||||
client,
|
||||
ctx,
|
||||
estimationId,
|
||||
});
|
||||
}
|
||||
|
||||
if (action === 'join') {
|
||||
return await joinSession({
|
||||
client,
|
||||
estimationId,
|
||||
userId,
|
||||
ctx,
|
||||
});
|
||||
}
|
||||
|
||||
return res.json(
|
||||
{
|
||||
message: 'Not found',
|
||||
},
|
||||
404,
|
||||
);
|
||||
};
|
||||
5
functions/EstimationSessionInvite/tsconfig.json
Normal file
5
functions/EstimationSessionInvite/tsconfig.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"types": ["bun-types"]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user