-
Notifications
You must be signed in to change notification settings - Fork 5
Project Structure
Lars Waage edited this page May 25, 2023
·
1 revision
-
frontend
contains the indokntnu.no web application, written in TypeScript with React and Next.js.-
src
contains the source code of the frontend.-
pages
contains page components, where each file corresponds to a URL on the website. For example,pages/about/board.tsx
is the component that is rendered at indokntnu.no/about/board. Files/folders in [brackets] are variables in the URL, sopages/about/organizations/[slug].tsx
gives access to theslug
variable in that page component, which is e.g.rubberdok
in indokntnu.no/about/organizations/rubberdok. -
components
contains React components used to build up the website.-
pages
(undercomponents
) are components for specific pages. The folder structure here mirrors the folders in the top-levelpages
, so components for the pages inpages/events
are incomponents/pages/events
. - Other folders here are for components used across pages.
-
-
layouts
contains React components that are part of the base website layout on every page, e.g. the navigation bar and footer. -
graphql
contains GraphQL requests that the frontend uses to talk to the backend API.- The folders here are grouped by backend app, so
graphql/events
contains queries/mutations for the backend app inbackend/apps/events
. - Each folder has:
-
queries.graphql
for requests that only fetch data. -
mutations.graphql
for requests that change data. -
fragments.graphql
for GraphQL fragments: a selection of fields on one of our API types, that can be reused across different queries/mutations to ensure consistent types. Whenever you see a...Fragment
type fromgenerated/graphql
, that type has been generated from afragments.graphql
file.
-
- The folders here are grouped by backend app, so
-
generated
contains output from code generation.-
graphql.ts
is the output fromgraphql-codegen
, the tool we run withyarn generate
. It reads our GraphQL schema (backend/schema.json
), and our queries, mutations and fragments (from thegraphql
folder), to generate TypeScript types and data for making requests to our backend API.
-
-
types
contains shared types used across the app. -
theme
contains customizations for Material UI, the styled component library we use for React.-
components
contains customizations for specific Material UI components.
-
-
lib
contains functions defined by us to make it easier to work with some of our libraries. -
utils
contains utility functions.
-
-
.husky
configures Husky, the tool we use for pre-commit hooks (checks that run on each Git commit). -
content
contains files for static content used by our React components. -
cypress
defines our Cypress end-to-end tests, which essentially involve a robot clicking through our website to check that everything works as expected. -
public
contains public files, such as images, served by our frontend. -
package.json
lists the TypeScript dependencies of the project, and also defines the scripts for use by Yarn. Runningyarn
installs the dependencies listed here, while running e.g.yarn dev
runs the command in"scripts": ... "dev":
. -
.eslintrc.json
configures ESLint, our linter (a tool to enforce code standards) for TypeScript. -
.prettierrc
configures Prettier, the tool we use to format our TypeScript code. -
codegen.yml
configuresgraphql-codegen
, the tool we use to generate TypeScript code from our backend's GraphQL API schema and the.graphql
files we write in our frontend. This is what runs in theyarn generate
command. -
tsconfig.json
configures the rules TypeScript should enforce when type checking our code. -
.env
files define the environment variables for the different environments of the project (development, production, testing).- To override environment variables for your local development environment, add a
.env.local
file with your variables. This file is ignored by Git.
- To override environment variables for your local development environment, add a
-
-
backend
contains the backend server at api.indokntnu.no, written in Python with Django and Graphene.-
api/auth
contains the logic for authenticating users on their requests. -
apps
contains the different Django apps (essentially modules) for the backend. Each app follows this structure (or at least parts of it):-
fixtures
contains example data for local development, loaded throughpython manage.py loaddata initial_data
. -
migrations
contains Django files for migrating (updating) the database after every change to a Django model in the app. Most of these are generated through thepython manage.py makemigrations
command, though some are custom-written for more complex updates of the database. The code in these files is what runs when you dopython manage.py migrate
. -
admin.py
configures what parts of the app should be shown in the Django admin panel. -
apps.py
configures the app. -
constants.py
contains constant values used by the app. -
dataloader.py
contains custom logic for loading data for particular GraphQL queries (read more here). -
models.py
defines the Django models of the app, which is how objects of the app are stored in the database. -
mutations.py
defines classes for each GraphQL mutation in the app's API (GraphQL requests that change data), and their arguments. -
resolvers.py
defines methods for resolving each GraphQL query in the app's API (GraphQL requests that only fetch data). -
schema.py
defines the GraphQL schema for the app's API. It imports the mutations and query resolvers frommutations.py
andresolvers.py
, and defines the types for the queries. -
signals.py
contains Django signals, which are functions that run on a specific trigger (e.g. when an object of a particular model is saved to the database). -
tests.py
contains tests of the app's logic. -
types.py
defines the GraphQL API types for models in the app. You can think of a type in this context as how an object is represented in our API (to our frontend), while a model is how it is represented in the database. An API type typically inherits from Graphene'sDjangoObjectType
and bases itself on the fields of its corresponding Django model. However, it can also add custom fields that are not on the database model, in which case it defines aresolve_[field_name]
on the type with the logic for resolving that field.
-
-
config
configures the Django project, and ties together the different apps.-
settings
contains Django settings for the project.-
base.py
has settings for every version of the project. -
local.py
has settings for local development of the project. -
production.py
has settings for the production environment (the live website) of the project.
-
-
urls
defines the URL endpoints of the backend server. It follows the same file structure assettings
. -
schema.py
defines the GraphQL schema for the whole API of the backend. It simply imports each app's schema from theirschema.py
files, and combines them.
-
-
decorators
defines our custom Python decorators, which are the functions used with the@
syntax. -
entrypoints
contains scripts for running the backend, used by Docker and our Continuous Integration pipelines. -
requirements
list the Python dependencies of our project, to make it easier to install with e.g.pip install -r requirements/local.txt
.-
base.txt
contains the main dependencies for all versions of the project. -
local.txt
includes our Python formatter and linter for development. -
production.txt
includes a library for logging production errors to Sentry, our error logging service.
-
-
static
contains static content served by our backend. -
templates
contains Django templates, which is HTML but with slots for inserting values in Python. -
utils
contains shared utility classes and functions for use by our backend. -
schema.json
is a JSON representation of the backend's GraphQL API schema defined in ourschema.py
files. It is generated with thepython manage.py graphql_schema
command, and can then be used by our frontend to generate TypeScript code for interacting with our API. So you can essentially think ofschema.json
as a language-agnostic "translation step" for letting the TypeScript frontend use the API types from our Python backend. -
mypy.ini
configures MyPy, a type checker for Python. -
pyproject.toml
configures Black, the tool we use to format our Python code. -
tox.ini
configures flake8, our linter (a tool to enforce code standards) for Python. -
.env
files contain the environment variables for the different environments of the project (development, production, testing).- To override environment variables for your local development environment, add a
.env
file with your variables. This file is ignored by Git.
- To override environment variables for your local development environment, add a
-
-
.gitignore
tells Git which files should not be included in the repository (these are grayed out in VSCode's file explorer). -
docker-compose.yml
configures the Docker containers that can be run with thedocker compose
command. Our frontend and backend also have aDockerfile
each for configuring their Docker containers.