Skip to content

Commit

Permalink
Merge branch 'staging'
Browse files Browse the repository at this point in the history
  • Loading branch information
BEDev24 committed Sep 13, 2024
2 parents dbc1b5e + b14b1be commit 90b202c
Show file tree
Hide file tree
Showing 43 changed files with 1,639 additions and 537 deletions.
1 change: 1 addition & 0 deletions .github/workflows/merge.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ env:
jobs:
check-build-deploy:
strategy:
fail-fast: false
matrix:
include:
- workdir: ./frontend
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ permissions:
jobs:
static-checks:
strategy:
fail-fast: false
matrix:
include:
- workdir: ./frontend
Expand Down
45 changes: 11 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,23 @@

Welcome to the official repository for the Constitution Committee Portal.

The primary purpose of the solution is to host the Cardano Constitution and allow anyone to get familiar with it and follow its evolution over time. It also serves as the single point of truth for the Cardano Community members to see how Constitutional Committee members voted on a specific Governance Action, with the inclusion of their rationale. For members of the Constitutional Committee, it serves as a portal to add reasoning to their votes and prepare it as an off-chain resource to be attached to on-chain governance actions.

## Navigation

- [Constitution Committee Portal](#constitution-committee-portal)
- [Navigation](#navigation)
- [Introduction](#introduction)
- [Instances](#instances)
- [Mainnet (beta)](#mainnet-beta)
- [SanchoNet](#sanchonet)
- [Prerequisites](#prerequisites)
- [Tech stack:](#tech-stack)
- [Frontend](#frontend)
- [Backend](#backend)
- [Database](#database)
- [Caching service](#caching-service)
- [Worker service](#worker-service)
- [IPFS/IPNS Helia node](#ipfsipns-helia-node)
- [Getting started](#getting-started)
- [Usage](#usage)
- [Environment Variables](#environment-variables)
- [API Documentation](#api-documentation)
- [License](#license)
- [Introduction](#introduction)
- [Prerequisites](#prerequisites)
- [Tech stack](#tech-stack)
- [Getting started](#getting-started)
- [Usage](#usage)
- [Environment Variables](#environment-variables)
- [API Documentation](#api-documentation)
- [License](#license)

## Introduction

The primary purpose of the solution is to host the Cardano Constitution and allow anyone to get familiar with it and follow its evolution over time. It also serves as the single point of truth for the Cardano Community members to see how Constitutional Committee members voted on a specific Governance Action, with the inclusion of their rationale. For members of the Constitutional Committee, it serves as a portal to add reasoning to their votes and prepare it as an off-chain resource to be attached to on-chain governance actions.

This document serves as a comprehensive guide for setting up the full stack of our application, which includes the Frontend, Backend, Database, Caching, Worker and IPFS components.

## Instances

### Mainnet (beta)

- [constitution.gov.tools](https://constitution.gov.tools/)

### SanchoNet

- [sancho.constitution.gov.tools](https://sancho.constitution.gov.tools/)

## Prerequisites

- Node.js installed - [Download link](https://nodejs.org/en/download/).
Expand Down Expand Up @@ -243,6 +222,4 @@ Access the API documentation at: [http://localhost:1337/api-docs](http://localho
## License
This project is licensed under the Apache 2.0.
See [License file](./LICENSE).
This project is licensed under the MIT License.
4 changes: 3 additions & 1 deletion backend/example.env
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@ EMAIL_FROM=example@email.from
NAME_FROM=Example Name From

#minio
MINIO_ENDPOINT=minio
MINIO_ENDPOINT=localhost
MINIO_PORT=9000
MINIO_ACCESS_KEY=minio
MINIO_SECRET_KEY=minio123
MINIO_USE_SSL=false
MINIO_BUCKET=cc-portal

S3_BASE_URL=http://localhost:9000

# IPFS Service
IPFS_SERVICE_URL=http://ipfs-service:3001

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class GovTitleAbstractLenRemoval1726048356332
implements MigrationInterface
{
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`begin;
ALTER TABLE gov_action_proposals
ALTER COLUMN title TYPE VARCHAR;
ALTER TABLE gov_action_proposals
alter COLUMN abstract type VARCHAR;
commit;`,
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`begin;
ALTER TABLE gov_action_proposals
ALTER COLUMN title TYPE VARCHAR(80);
ALTER TABLE gov_action_proposals
alter COLUMN abstract type VARCHAR(2500);
commit;`,
);
}
}
2 changes: 0 additions & 2 deletions backend/src/constitution/facade/constitution.facade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { ConstitutionRedisService } from 'src/redis/service/constitution-redis.s
import { ConstitutionResponse } from '../api/response/constitution.response';
import { ConstitutionMapper } from '../mapper/constitution.mapper';
import { ConstitutionDto } from 'src/redis/dto/constitution.dto';
import { ConstitutionService } from '../services/constitution.service';
import { IpfsService } from 'src/ipfs/services/ipfs.service';
import { ConstitutionMetadataResponse } from '../api/response/constitution-metadata.response';
import { ConstitutionIpnsUrlResponse } from '../api/response/constitutio-ipns-url.response';
Expand All @@ -14,7 +13,6 @@ export class ConstitutionFacade {

constructor(
private readonly constitutionRedisService: ConstitutionRedisService,
private readonly constitutionService: ConstitutionService,
private readonly ipfsService: IpfsService,
) {}

Expand Down
7 changes: 5 additions & 2 deletions backend/src/governance/facade/governance.facade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ export class GovernanceFacade {
const response = await this.governanceService.addRationale(rationaleDto);
return GovernanceMapper.rationaleDtoToResponse(response);
}

/**
* Creates a CIP 100 compatible JSON object.
* CIP 100 example:
* https://github.com/cardano-foundation/CIPs/blob/master/CIP-0100/example.body.json
**/
private async createRationaleJsonCip100(
rationaleRequest: RationaleRequest,
): Promise<string> {
Expand Down Expand Up @@ -97,7 +101,6 @@ export class GovernanceFacade {
hashAlgorithm: CIP100.hashAlgorithm,
authors: [],
body: {
references: [],
comment: rationaleRequest.content,
},
};
Expand Down
1 change: 0 additions & 1 deletion backend/src/governance/interfaces/icip100.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,5 @@ interface WitnessContext {
}

interface BodyContent {
references: any[];
comment: string;
}
3 changes: 2 additions & 1 deletion backend/src/ipfs/services/ipfs.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ export class IpfsService {
const formData = new FormData();
formData.append('file', blob, file.originalname);

const apiLink = this.configService.getOrThrow('IPFS_SERVICE_URL') + '/ipfs';
const apiLink =
this.configService.getOrThrow('IPFS_SERVICE_URL') + '/ipfs/file';
const requestConfig = {
headers: {
'Content-Type': 'multipart/form-data',
Expand Down
7 changes: 5 additions & 2 deletions backend/src/s3/service/s3.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ export class S3Service {
const buffer = Buffer.from(bufferArray);

const fullName = this.getFullFileName(context, fileName);
await this.client.putObject(this.bucketName, fullName, buffer, file.size);
await this.client.putObject(this.bucketName, fullName, buffer, file.size, {
'Content-Type': file.mimetype,
});

const fileUrl = await this.getFileUrl(context, fileName);
return fileUrl;
Expand All @@ -34,7 +36,8 @@ export class S3Service {
fileName: string,
): Promise<string> {
const fullName = this.getFullFileName(context, fileName);
return await this.client.presignedUrl('GET', this.bucketName, fullName);
const fileUrl = `${this.configService.get('S3_BASE_URL')}/${this.bucketName}/${fullName}`;
return fileUrl;
}

async deleteFile(fileName: string) {
Expand Down
5 changes: 4 additions & 1 deletion docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ services:
dockerfile: Dockerfile
container_name: ipfs-service
volumes:
- ipfs_data:/app/
- ipfs_data:/ipfs/datastore
networks:
- cc
extra_hosts:
Expand Down Expand Up @@ -68,6 +68,9 @@ services:
image: redis/redis-stack:latest
container_name: cache
restart: always
environment:
- REDIS_PASSWORD=your-redis-password
command: redis-server --requirepass ${REDIS_PASSWORD}
ports:
- '6379:6379'
volumes:
Expand Down
8 changes: 7 additions & 1 deletion frontend/example.env
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
NEXT_PUBLIC_API_URL=http://backend:1337 # Container name goes here
NEXT_PUBLIC_API_URL=http://backend:1337 # Container name goes here
NEXT_PUBLIC_USERSNAP_SPACE_API_KEY=
NEXT_PUBLIC_USERSNAP_PROJECT_API_KEY =
NEXT_PUBLIC_HIDDEN_USERSNAP_PROJECT_IDS=
NEXT_PUBLIC_IS_MAINNET=false


10 changes: 5 additions & 5 deletions frontend/messages/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -243,27 +243,27 @@
},
"members": {
"title": "No members found",
"description": "There is currently no members. Please check back later for updates"
"description": "There are currently no members. Please check back later for updates"
},
"latestUpdates": {
"title": "No votes found",
"description": "There is currently no votes. Please check back later for updates"
"description": "There are currently no votes. Please check back later for updates"
},
"myActions": {
"title": "No votes found",
"description": "There is currently no votes. Please check back later for updates"
"description": "There are currently no votes. Please check back later for updates"
},
"constitution": {
"title": "No Constitution available",
"description": "There is currently no Constitution uploaded. Please check back later for updates"
},
"constitutionMetadata": {
"title": "No revisions available",
"description": "There is currently no revisions available. Please check back later for updates"
"description": "There are currently no revisions available. Please check back later for updates"
},
"governanceAction": {
"title": "No governance actions available",
"description": "There is currently no governance actions. Please check back later for updates"
"description": "There are currently no governance actions. Please check back later for updates"
}
},
"Snackbar": {
Expand Down
10 changes: 5 additions & 5 deletions frontend/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -243,27 +243,27 @@
},
"members": {
"title": "No members found",
"description": "There is currently no members. Please check back later for updates"
"description": "There are currently no members. Please check back later for updates"
},
"latestUpdates": {
"title": "No votes found",
"description": "There is currently no votes. Please check back later for updates"
"description": "There are currently no votes. Please check back later for updates"
},
"myActions": {
"title": "No votes found",
"description": "There is currently no votes. Please check back later for updates"
"description": "There are currently no votes. Please check back later for updates"
},
"constitution": {
"title": "No Constitution available",
"description": "There is currently no Constitution uploaded. Please check back later for updates"
},
"constitutionMetadata": {
"title": "No revisions available",
"description": "There is currently no revisions available. Please check back later for updates"
"description": "There are currently no revisions available. Please check back later for updates"
},
"governanceAction": {
"title": "No governance actions available",
"description": "There is currently no governance actions. Please check back later for updates"
"description": "There are currently no governance actions. Please check back later for updates"
}
},
"Snackbar": {
Expand Down
14 changes: 7 additions & 7 deletions frontend/src/app/[locale]/my-actions/page.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import React, { Suspense } from "react";
import { Suspense } from "react";

import { unstable_setRequestLocale } from "next-intl/server"; // Import function to set the request-specific locale (unstable API).
import { Footer, TopNav, MyActions } from "@organisms";
import { Loading } from "@molecules";
import { decodeUserToken, getUserVotes } from "@/lib/api";
import { ContentWrapper } from "@atoms";
import { Loading } from "@molecules";
import { Footer, MyActions, TopNav } from "@organisms";
import { isResponseErrorI } from "@utils";
import { unstable_setRequestLocale } from "next-intl/server"; // Import function to set the request-specific locale (unstable API).

export default async function MyActionsPage({
params: { locale },
searchParams,
searchParams
}) {
unstable_setRequestLocale(locale); // Sets the locale for the request. Use cautiously due to its unstable nature.
const user = await decodeUserToken();
Expand All @@ -19,10 +19,9 @@ export default async function MyActionsPage({
govActionType: searchParams?.govActionType,
vote: searchParams?.vote,
sortBy: searchParams?.sortBy,
userId: user?.userId,
userId: user?.userId
});
const hasError = isResponseErrorI(userActions);

return (
<>
<TopNav />
Expand All @@ -32,6 +31,7 @@ export default async function MyActionsPage({
actions={!hasError && userActions?.data}
paginationMeta={!hasError && userActions?.meta}
error={hasError && userActions.error}
userId={user?.userId}
/>
;
</Suspense>
Expand Down
15 changes: 8 additions & 7 deletions frontend/src/components/atoms/OutlinedLightButton.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
"use client";

import React from "react";
import { Button, SxProps, Theme } from "@mui/material";
import { customPalette } from "@consts";
import { Button, SxProps, Theme } from "@mui/material";
import { ButtonProps } from "@mui/material/Button";

interface Props extends ButtonProps {
Expand All @@ -23,11 +22,13 @@ export const OutlinedLightButton = ({
color: customPalette.textBlack,
fontWeight: 400,
fontSize: 12,
whiteSpace: "nowrap",
lineHeight: "18px",
wordBreak: "break-word",

"&": {
pointerEvents: nonInteractive ? "none" : "all",
},
};
pointerEvents: nonInteractive ? "none" : "all"
}
} as React.CSSProperties;

return (
<Button
Expand All @@ -36,7 +37,7 @@ export const OutlinedLightButton = ({
onClick={nonInteractive ? undefined : onClick}
sx={{
...defaultSxProps,
...sx,
...sx
}}
{...props}
>
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/components/molecules/TableDivider.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { customPalette } from "@/constants";
import { Divider as MUIDivider, DividerProps, SxProps } from "@mui/material";
import { DividerProps, Divider as MUIDivider, SxProps } from "@mui/material";

interface Props extends DividerProps {
sx?: SxProps;
Expand All @@ -16,10 +16,10 @@ export const TableDivider = ({
orientation={orientation}
flexItem={flexItem}
sx={{
display: { xxs: "none", lg: "flex" },
display: { xxs: "none", md: "flex" },
height: 38,
alignSelf: "center",
...sx,
...sx
}}
{...props}
/>
Expand Down
Loading

0 comments on commit 90b202c

Please sign in to comment.