Portal is ACM-UTSA's in-house registration, member management, and database system.
- Register, manage, and track members
- Member attendance turns into points, granting membership benefits
- Create, display, and manage events
- Track attendance with custom points
- Built on Next.js + tRPC and Prisma
- SSR, ISR, and SSG for fast, dynamic, and static pages
- Tailwind-style CSS with HeadlessUI
- Next.js deployed on Vercel
- tRPC (supported by TanStack Query)
- React
- Prisma
- Typescript
- Sentry
- Typeform
- Zod
- Prettier, Sharp, superjson, Nprogress
See package.json
for all other requirements. Bootstrapped using Create T3 App.
- Node.js
- Use Node v18 (LTS). Anything higher or lower may not be compatible.
- Yarn
npm install --global yarn
- Note: While
yarn
is the package manager,npx
is recommended for executingprisma
commands.
- PostgreSQL
For easy development, yarn run dev
will start Next.js with hot-reloading & error reporting.
Build for production with yarn run build
for a production-ready version of the site.
To execute it locally, execute yarn run start
. Features like hot-reloading will not be available.
Analysis of package sizes in a built website can be conducted with yarn run analyze
; this will build like yarn run build
,
but will generate (and open) build reports useful for understanding the site's webpack size.
Lastly, some environment variables are required. In .env
, define these variables (values are your choice, but must not be null):
ADMIN_UNAME=acm
ADMIN_PASS=123
EVENT_PAGE_REVALIDATION_TIME=2
Prisma, our choice of Database ORM, requires a database to operate upon for nearly all interactions. If you are an ACM Officer working on this project, contact the appropriate officer to acquire the Database URL.
The database URL should be placed in .env
in the root directory:
DATABASE_URL=postgresql://{username}:{password}@{domain}:{port}/{database}
Under no circumstances should this file be removed from .gitignore
and committed to any branch.
If you don't have access to that database URL and would like a local database instance to work with, Docker is an excellent option.
version: '3.8'
services:
db:
image: postgres:latest
restart: always
environment:
- POSTGRES_USER=admin
- POSTGRES_PASSWORD=password
- POSTGRES_DB=postgres
ports:
- '39755:5432'
volumes:
- db:/var/lib/postgresql/data
volumes:
db:
driver: local
Paste the above inside a docker-compose.yml
file (anywhere), then execute docker-compose up -d
to run it in the background.
To stop the container, execute docker-compose stop
, and to delete it, docker-compose rm --stop
(stop & delete).
Find more commands here.
The DATABASE_URL
here would be postgresql://admin:password@localhost:39755/postgres
.
The port mapping chosen here is arbitrary (high port number reduces chances of appearance in a port exclusion range).
Change as you wish. Details here.
Once created, the database will need to be updated with the current schema. Execute npx prisma db push
.
This command should not be used for existing DBs.
Prisma's database should be very carefully migrated, especially so in production environments. If you do not have 100% confidence in what you are doing, you should not be attempting to migrate the database.
- Someone else migrated the database and now my version doesn't match up!
git checkout main
andgit pull
. Unless something is going wrong, the latest database migration should be committed intomain
.- Execute
npx prisma generate
. This will generate a new query engine and update your bindings forcibly.npx
forces execution of the latest version of Prisma, ensuring the latest version (and not whatever is in your local installation) is used.
With our client and server so closely outfitted together, it is important to know how easily the client may try to access resources it simply should not be attempting to. This is primarily when dealing with environment variables.
Like most web applications, ours is provided credentials to the services it needs through environment variables; database URLs and such. A number of other important pieces of data are accessed here as well, such as the static administrator login and the environment type.
Here is one simple example of how importing something in the wrong spot can lead to the client breaking.
/member/status.tsx
includes{ OpenGraph }
fromOpenGraph.tsx
OpenGraph.tsx
includes{ ltrim }
fromutils/helpers.ts
utils/helpers.ts
containsvalidateMember
, which has a type ofMember
, re-exported from@prisma/client
inside/server/db/client.ts
- This is nothing more than a type, not a function or constant, used for the Typescript transpiler.
/server/db/client.ts
uses theNODE_ENV
environment variable provided to the server.
The issue here is that helpers.ts
contains methods that access server-side resources whilst being
accessed by the client. If a server-side resource is being accessed, it should be moved to not
be alongside client-side methods.