Skip to content

Donnerstagnacht/polity

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Polity - Vision


The goal of polity is to create a - theoretically - global real-time decision platform for political parties, individuals and public bodies.

Our Goal & Figma Clickdummy πŸš€
Clickdummy

Current development state - prototype (daily database reset)
Prototype

Message tobias.hassebrock@gmail.com to gain access to the Figma Design files.


Support the project

You are heartly welcome to collaborate on the project. I created a few tasks in the project section. In case of any questions reach out to me. Besides that, I am open to any kind of new feature which might benefit public decision making.

Discord server:
Discord
πŸ‘‰Issues

πŸ‘‰Projects

Contact:
tobias.hassebrock@gmail.com

Drop me a message/pull request here on GitHub or per mail if you are interested in supporting the project.


Get startet with development

  1. Clone the repo
    git clone https://github.com/Donnerstagnacht/polity.git
  2. Install Node-Js
    https://nodejs.org/en/
  3. Install NPM packages
    npm install
  4. Set up local development for supabase
    https://supabase.com/docs/guides/cli/local-development
    
    Enable webhooks in the supabase dashboard or create a "supabase_functions" schema manually.
    Update environment variables (supabaseProjectUrl, supabaseAnonKey, supabaseRoleLevelSecurityKeys VAPID_Keys ) in 
       - src/environments/environment.ts
       - supabase/migrations/<all files with webhook>
       - the .bat files
    Update redirect links in the Auth Service.
    
    Optional: Set up a remote environment on supabase.com
  5. Start Angular dev server
    ng serve

Techstack

Polity is based 100% on OpenSource technologies and is self-hostable.


Dataflow

Data is queried mostly by PostgreSQL functions. The functions are executed in a wrapper service that handles loading and UI flags.

Additionally, a Supabase real-time subscription is used to update the store (and therefore the UI) pessimistically whenever subscribed data in the database is changed.

To display data to the user, the data is stored in Angular Signals.

*** Data in ***
User  --> PostgreSQL function --> Database --> UI

*** Data out: ***
Database --> Query Function and/or real-time subscription --> Signal Store--> UI --> User

Summary: Most business logic is transferred to powerful PostgreSQL functions.


Project Structure

Angular files are organized in the src/app. Subfolders mirror app features and mostly correspond to the available routes.

Cypress files are organized in the Cypress/e2e folder and the file order should be identical to the test execution order.

Supabase files are organized in the supabase/migrations folder with subdirectories according to features. These files must have a prefix that determines the migration/execution order.

Most important project directories and files:

.
β”œβ”€β”€ cypress: End-2-End tests organized by features
β”‚    β”œβ”€β”€ e2e: End to end tests ordered by execution
β”‚    β”‚    └── Feature: according to front end
β”‚    β”œβ”€β”€ fixtures: specific test variables
β”‚    └──  support
β”‚          β”œβ”€β”€ commands: Definition of cypress commonands
β”‚          └── index.d.ts: Signature and types of cypress commands
β”‚       
β”œβ”€β”€ seed_and_test_data
β”‚    └── Data used to seed database and set test states
β”‚
β”œβ”€β”€ src
β”‚    β”œβ”€β”€ app: Frontend
β”‚    β”‚    β”œβ”€β”€ auth: Authentication functionality
β”‚    β”‚    β”œβ”€β”€ features: Features organized by routing
β”‚    β”‚    β”‚    └── feature: One feature module
β”‚    β”‚    β”‚         β”œβ”€β”€ components: Presentation logic
β”‚    β”‚    β”‚         β”œβ”€β”€ routes: Routes of the feature
β”‚    β”‚    β”‚         β”œβ”€β”€ store: Front end store instantiations
β”‚    β”‚    β”‚         β”œβ”€β”€ actions: Link between database and frontend store
β”‚    β”‚    β”‚         └── guards: Protecting routes
β”‚    β”‚    β”œβ”€β”€ landing: Non-authenticated features (landing website before sign-in)
β”‚    β”‚    β”œβ”€β”€ navigation
β”‚    β”‚    β”œβ”€β”€ signal-store: Frontend data store
β”‚    β”‚    └── ui: Pure UI components
β”‚    β”œβ”€β”€ assets: static files
β”‚    β”œβ”€β”€ environments: Supabase parameter
β”‚    └── styles-global: Global style sheets
β”‚         β”œβ”€β”€ Global component styles
β”‚         β”œβ”€β”€ Polity utility styles
β”‚         └── TUI extensions & overwrites
β”‚
β”œβ”€β”€ supabase: Supabase / Backend, directories by feature, but file execution by prefix
β”‚    β”œβ”€β”€ Functions: Supabase edge functions
β”‚    β”œβ”€β”€ migrations
β”‚    β”‚    └── feature: according to frontend feature
β”‚    β”‚         β”œβ”€β”€ Schemas and other
β”‚    β”‚         β”œβ”€β”€ Database types/ Enums/Table definitions
β”‚    β”‚         β”œβ”€β”€ schema/Table definitions
β”‚    β”‚         β”œβ”€β”€ Database functions/queries 
β”‚    β”‚         β”œβ”€β”€ Database transactions (calling other functions)
β”‚    β”‚         └── Database seed
β”‚    └── types
β”‚         β”œβ”€β”€ supabase.public.modified.ts: Overwritten supabase types since generation is not always correct
β”‚         β”œβ”€β”€ supabase.authenticated.shorthand-types.ts: Short-handed supabase types for easier usage in Front End code
β”‚         └── supabase.ts: Auto-generated supabase types
β”‚
β”œβ”€β”€ copy_sql_files_to_migration_folder: A windows bat file to copy supabase files into the migration directory so that automatic migration can be executed
β”œβ”€β”€ package.json: Project dependencies
└── cypress.config.ts: Cypress configuration

Schematics

Polity includes an angular schematic package which can be used to generate store modules or database elements/features. This can speed up development and ease the implementation of the strict and required naming conventions for PostgreSQL migration files.

To start with polity schematics run:

  1. Switch to schematics directory

    src\polity-signal-store\schematics\supabase
  2. Build the schematic

    npm run build
  3. Switch to the root component or open a new terminal

    cd ../../../..
  4. Link the schematic

    npm link src\polity-signal-store\schematics\supabase --force
  5. Use the schematic

    ng g db:<schematic_name>   <arguments> 
    ng g db:array profiles   read_profiles   src/app/features

Available commands

Comman Description Arguments
array Generating an angular signal array store. name
rpc_name
path
object Generating an angular signal object store. name
rpc_name
path
enum Generates a postgres enum. name
supabse_feature_id
path
feature Generates a postgres feature (table, policies, CRUD functions). name
supabse_feature_id
path
policies Generates a postgres policy set. name
supabse_feature_id
path
rpc Generates a postgres rpc. name
supabse_feature_id
path
storage Generates a postgres storage. name
supabse_feature_id
path
table Generates a postgres table. name
supabse_feature_id
path
trigger Generates a postgres trigger. name
supabse_feature_id
path

Naming conventions

PostgreSQL code and code or variables that are used to call PostgreSQL functions should be written in lowercase with underscores e.g. a_variable_for_a_postgres functions.. Parameters and return table variables of postgres functions should be prefixed with a "_" (e.g. _parameter) to avoid ambitous naming conflicts. Prefer table returns and table composite type above defining custom types, since custom types do not allow constraints (e.g. not null and supabase type generation adds "| null" to each property.

Postgres migration files are applied in descending sequential order, must be unique and named like timestamp_name.sql. The codestamp must have a minimum of 6 digits and a maximum of 14 digits. After that an "_" must follow. Files which determine the initial setup do not use a timestamp. Instead, a numbercode is used to gurantee a certain execution order.

The number code is:

numbercode = 000 + two digit number implying the postgres object type _ three digit running number _ six digit number determining the featuere.

The two digit number code is mapped to postgres types to ensure that postgres objects are created in the correct order (since objects on lower table lines depend on higher table lines):

Code Description
00 Pre migration tasks (types, resets, schemas...)
01 Enums
10 Tables, indexes, row level security settings
20 Row level security policies
30 Triggers and trigger related functions
60 Functions
80 Transactions (functions that depend on other functions)
98 Post migration tasks (bug fixes...)
99 Database/table seeding

The three digit running number is simply a running number except for the Standalone Functions (Code 60). Here, functions should order by Create, read, update, delete and others.

Code Description
0xx Functions for create operations (insert or upsert)
1xx Functions for read operations
2xx Functions for update operations
3xx Functions for delete operations
4xx Other functions (checks, increments, decrements...)

The feature is a unique 6 diigt code. Main features should be "thousand steps" (for example: 001000 = profiles).

The leading "000" prefix is added by a scipt.

For purely frontend-related variables code camelCase is used e.g. aVariableForTheFrontend.

HTML elements used for testing should contain the attribute [attr.data-cy]="'element-name'". The attribute name uses "-" seperators.

In general, use speaking names and choose a longer more specific name over a short unspecific name.


Documentation

Document public functions (especially in services).


Database security

Polity applies a database security layer concept with the following layers

Layername Description
public A public layer available to all roles. An API is generated automatically.
authenticated A layer available to the "authenticated" role (logged in users). An API is generated automatically.
hidden A hidden layer that can only be accessed by functions (e.g. available to "authenticated" role but no API generated. This includes all tables.
security A hidden layer that can only be accessed by the postgres role. It is used to store helper functions for row level security checks.
postgres A hidden layer that can only be accessed by the postgres role. Used to store triggers.

Additionally, each table is secured with row level security policies. Row level security policies check data access for each row. While this architecture disables the quick usage of the autogenerated supabase api, it decreases the attack vector to the parameters of functions of the public/authenticated layer. To strengthen this even further, it should be avoided to pass the id of the authenticated user as argument to a function. Instead, supabase heper functions like auth.uid() should be used directly in the database function

Functions from the hidden layer should always raise an error if they fail.


Testing Approach

The project uses no unit tests so far. However, all features should be committed with a working Cypress end-to-end test that covers at least the expected positive base-line scenario, e.g. the workflows possible in the GUI

To facilitate database security, negative scenarios (e.g. database calls which should not return results because they are not allowed) should be tested using Cypress api call tests.


Recommended "Definition of Done" Checklist

This is not mandatory - but a guideline:

  1. Check naming conventions
  2. Document public functions
  3. Implement end-to-end-tests
  4. Pass all existing end-to-end-test to ensure code compatibility

Local development server Frontend (Angular)

Run ng serve for a dev server. Navigate to http://localhost:4200/.

Local development server Backend (Supabase)

Run supabase start for a local dev server. Navigate to http://localhost:54323/. Follow the local development guide of Supabase to reset or reload your environment

Local running Cypress end-to-end tests

Run npm run e2e_open to open the Cypress test runner and execute tests without resetting your Supabase environment. Run npm run e2e_run to run the e2e test in your command line.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published