Skip to content

Commit

Permalink
Update documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
fzaninotto committed Aug 20, 2024
1 parent d3fd05b commit 46ef649
Show file tree
Hide file tree
Showing 27 changed files with 536 additions and 464 deletions.
48 changes: 24 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Atomic CRM

A full-feature CRM built with React and Supabase.
A full-feature CRM built with React and Supabase.

https://user-images.githubusercontent.com/99944/116970434-4a926480-acb8-11eb-8ce2-0602c680e45e.mp4

You can test it online at https://marmelab.com/react-admin-crm.

## Install Project
## Installation

To run this project locally, you will need the following tools installed on your computer:

Expand All @@ -29,18 +29,6 @@ make install

This will install the dependencies for the frontend and the backend, including a local Supabase instance.


## Developing with Atomic CRM

### Local Development Setup

1. [Supabase Configuration](./doc/developer/dev-01-supabase-configuration.md)
2. [Customizing the CRM](./doc/developer/dev-02-customizing.md)
3. [Creating Migrations](./doc/developer/dev-03-supabase-migrations.md) *(optional)*
4. [Contact Import Customization](./doc/developer/dev-04-contact-import.md) *(optional)*
5. [Using Fake Rest Data Provider for Development](./doc/developer/dev-O5-data-providers.md) *(optional)*
6. [Learn More About Architecture Decisions](./doc/developer/dev-06-architecture-choices.md) *(optional)*

Once you app is configured, start the app locally with the following command:

```sh
Expand All @@ -49,7 +37,7 @@ make start

This will start the Vite dev server for the frontend, the local Supabase instance for the API, and a Postgres database (thanks to Docker).

You can then access the app via [http://localhost:5173/](http://localhost:5173/).
You can then access the app via [http://localhost:5173/](http://localhost:5173/). You will be prompted to create the first user.

If you need debug the backend, you can access the following services:

Expand All @@ -58,21 +46,33 @@ If you need debug the backend, you can access the following services:
- Attachments storage: [http://localhost:54323/project/default/storage/buckets/attachments](http://localhost:54323/project/default/storage/buckets/attachments)
- Inbucket email testing service: [http://localhost:54324/](http://localhost:54324/)

### Deploying to Production
## User Documentation

1. [User Management](./doc/user/user-management.md)
2. [Importing And Exporting Data](./doc/user/import-contacts.md)
3. [Inbound Email](./doc/user/inbound-email.md)

1. [Manual Production Deploy](./doc/developer/prod-01-manual-deploy.md)
2. [GitHub Actions Configuration](./doc/developer/prod-02-github-actions.md) *(optional)*
3. [Email Inbound Configuration](./doc/developer/prod-03-email-inbound.md) *(optional)*
## Deploying to Production

### Testing
1. [Configuring Supabase](./doc/developer/supabase-configuration.md)
2. [Configuring Inbound Email](./doc/developer/inbound-email-configuration.md) *(optional)*
3. [Deployment](./doc/developer/deploy.md)

## Customizing Atomic CRM

To customize Atomic CRM, you will need TypeScript and React programming skills as there is no graphical user interface for customization. Here are some resources to assist you in getting started.

1. [Customizing the CRM](./doc/developer/customizing.md)
2. [Creating Migrations](./doc/developer/migrations.md) *(optional)*
3. [Using Fake Rest Data Provider for Development](./doc/developer/data-providers.md) *(optional)*
4. [Architecture Decisions](./doc/developer/architecture-choices.md) *(optional)*

## Testing Changes

This project contains unit tests. Run them with the following command:

```sh
make test
```

## User documentation

1. [Create First User](./doc/user/01-create-first-user.md)
2. [Import Contacts](./doc/user/02-import-contacts.md)
You can add your own unit tests powered by Jest anywhere in the `src` directory. The test files should be named `*.test.tsx` or `*.test.ts`.
32 changes: 32 additions & 0 deletions doc/developer/architecture-choices.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Architecture Choices

This document explains some of the architecture decisions made in the development of Atomic CRM.

## Views

Some pages in Atomic CRM require data from multiple tables. To simplify the frontend code and reduce the HTTP overhead, Atomic CRM uses database views to abstract the complexity of the queries.

For instance, the contact list page displays the number of tasks for each contact. This information is provided by the `contacts_summary` view, defined in the `supabase/migrations/init_db.sql` file.

When using [the FakeRest data provider](./data-providers.md#setting-up-the-fakerest-data-provider), these views are emulated in the frontend.

## Triggers

User credentials are stored in Supabase's `auth.users` table. Supabase does not allow to add columns tp this table. That's why additional user details are stored in a `sales` table created by Atomic CRM. A database trigger is used to automatically sync the `sales` record when a user is created or updated (e.g. for the `first_name` and `last_name` fields).

The trigger can be found in the `supabase/migrations/init_triggerssql` file.

## Edge Functions

Due to the limitations of Supabase, the API does not have a public endpoint to manage users.

To solve this problem, Atomic CRM uses a `users` edge function in charge of:

- Verifying the current user's permissions
- Creating and updating users

Atomic CRM does not support user deletion to avoid data losses. Yet, it is possible to disable a user's account (relying on Supabase's ban feature).

Atomic also uses Edge functions to handle the webhook and process the received emails. Check the [Inbound Email](./inbound-email.md) documentation for more information.

The edge functions can be found in the `supabase/functions/` directory.
105 changes: 105 additions & 0 deletions doc/developer/customizing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Customizing Atomic CRM

Developers can customize the Atomic CRM application to suit their business needs. Some of the customizations can be achieved via configuration on the `<CRM>` component, while others require changes to the source code.

## The `<CRM>` component

The entry point of the frontend application is the `src/App.tsx` file. By default, this file simply renders the `<CRM>` component, which is the root component of Atomic CRM.

```tsx
import { CRM } from './root/CRM';

const App = () => <CRM />;

export default App;
```

`<CRM>` accepts various props to customize the application domain and look and feel, so the `App.tsx` file is the best place to configure your CRM.

For instance, the following code snippet shows how to customize the CRM application title, logo, themes, and domain-specific data.

```tsx
import { CRM } from './root/CRM';
import { radiantLightTheme, radiantDarkTheme } from 'react-admin';

const App = () => (
<CRM
title="ACME CRM"
logo="./img/logo.png" // The logo path is relative to the public directory
lightTheme={radiantLightTheme}
darkTheme={radiantDarkTheme}
contactGender={[
{ value: 'male', label: 'He' },
{ value: 'female', label: 'She' },
]}
companySectors={['Technology', 'Finance']}
dealCategories={['Copywriting', 'Design']}
dealPipelineStatuses={['won']}
dealStages={[
{ value: 'opportunity', label: 'Opportunity' },
{ value: 'proposal-sent', label: 'Proposal Sent' },
{ value: 'won', label: 'Won' },
{ value: 'lost', label: 'Lost' },
]}
noteStatuses={[
{ value: 'cold', label: 'Cold', color: '#7dbde8' },
{ value: 'warm', label: 'Warm', color: '#e8cb7d' },
{ value: 'hot', label: 'Hot', color: '#e88b7d' },
]}
taskTypes={['Call', 'Email', 'Meeting']}
/>
);

export default App;
```

`<CRM>` accepts the following props:

| Props | Description | Type |
|-----------------------|-----------------------------------------------------------------------|-----------------|
| contactGender | The gender options for contacts used in the application. | ContactGender[] |
| companySectors | The list of company sectors used in the application. | string[] |
| darkTheme | The theme to use when the application is in dark mode. | RaThemeOptions |
| dealCategories | The categories of deals used in the application. | string[] |
| dealPipelineStatuses | The statuses of deals in the pipeline used in the application | string[] |
| dealStages | The stages of deals used in the application. | DealStage[] |
| lightTheme | The theme to use when the application is in light mode. | RaThemeOptions |
| logo | The logo used in the CRM application. | string |
| noteStatuses | The statuses of notes used in the application. | NoteStatus[] |
| taskTypes | The types of tasks used in the application. | string[] |
| title | The title of the CRM application. | string |

## Customizing The Theme

Atomic CRM uses the Material-UI library for theming. You can customize the light and dark themes by setting the `lightTheme` and `darkTheme` props on the `<CRM>` component.

Check out react-admin's [theming documentation](https://marmelab.com/react-admin/Theming.html) for more information on how to customize the themes.

## Customizing The Layout

The components that make up the layout of the application (menu, container, etc) are located in the `src/layout` directory. You can customize the layout by modifying these components.

## Customizing the Homepage

The home page of the application is rendered by the `Dashboard.tsx` component. Updating this file to customize the dashboard.

Here is a simple example of a customized dashboard:

```jsx
// ./src/dashboard/Dashboard.tsx
import React from 'react';
import { Card, CardContent, Typography } from '@mui/material';

export const Dashboard = () => (
<Card>
<CardContent>
<Typography variant="h5" component="div">
Welcome to the Custom Dashboard!
</Typography>
<Typography variant="body2" color="text.secondary">
This is a customized homepage for your application. You can add any components or content here to suit your needs.
</Typography>
</CardContent>
</Card>
);
```
34 changes: 34 additions & 0 deletions doc/developer/data-providers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Data Providers

By default, the CRM demo uses [Supabase](https://supabase.com) for the backend API. Supabase is an open-source alternative to Firebase, built on top of Postgres. It provides a REST API and a real-time subscription system. The generous free tier allows you to run a small CRM for free.

## Using A Fake API For Development

For development purposes, you can use an alternative data provider called [FakeRest](https://github.com/marmelab/FakeRest). It's a simple REST API running in the browser that resets the data on each page reload. It's useful for testing the frontend without having to set up a backend, e.g. to let end users test some updates before the backend is ready.

FakeRest is used in the [React Admin CRM demo](https://marmelab.com/react-admin-crm/), where you can test it live.

### Setting Up The FakeRest Data Provider

To set up the FakeRest data provider, you need to change the `dataProvider` import in the `src/App.tsx` file:

```diff
// in src/App.tsx
import { CRM } from './root/CRM';
+ import { dataProvider, authProvider } from './providers/fakerest';

const App = () => (
<CRM
+ dataProvider={dataProvider}
+ authProvider={authProvider}
/>
);

export default App;
```

### Filters Syntax

The list filters used in this project MUST follow the [`ra-data-postgrest`](https://github.com/raphiniert-com/ra-data-postgrest) convention, where the filter operator is concatenated to the field name with an `@`. For example, to filter contacts by first name, you would use the `first_name@eq` filter.

When using FakeRest, the filters are mapped at runtime to the FakeRest filter syntax by the the [`supabaseAdapter`](../../src/providers/fakerest/internal/supabaseAdapter.ts) file. If a filter is not yet supported by the adapter, you have to modify this file to add support for it.
73 changes: 73 additions & 0 deletions doc/developer/deploy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Deploying to Production Manually

## Deploying The Backend

The entire backend of Atomic CRM is hosted on Supabase. The backend is composed of a Postgres database, a REST API, and edge functions. Check out the [Supabase Configuration](./supabase-configuration.md) section for details.

After configuring your Supabase instance, you can deploy the backend changes with the following command:

```sh
make supabase-deploy
```

## Testing Production Mode

If you want to test you local frontend code using the remote Supabase instance and the production settings, you can run the following command:

```sh
make prod-start
```

Note: It will apply migrations and deploy edge functions.

You can then access the app via [`http://localhost:3000/`](http://localhost:3000/).

## Deploying The Frontend

The frontend of the CRM is a Single-Page App that can be deployed to any CDN, or to GitHub Pages.

First, build the fontend bundle with:

```sh
make build
```

This will create a `dist` directory with the built application made of static HTML, CSS, and JS files. Upload this directory to the CDN of your choice.

If you want to deploy it to GitHub pages, you can use the following command:

```sh
npm run ghpages:deploy
```

The CRM will be available at `https://<username>.github.io/atomic-crm/`.

## Deploying Updates

If you've modified the code, run the following command to deploy a new version of your CRM:

```sh
make prod-deploy
```

It will apply migrations, deploy edge functions and push the built applications to the `gh-pages` branch.

## Automating Deployments With GitHub Actions

Atomic CRM contains GitHub actions for continuous integration and delivery. To enable these actions, you will
have to create the following secrets on GitHub:

```bash
SUPABASE_ACCESS_TOKEN: Your personal access token, can be found at https://supabase.com/dashboard/account/tokens
SUPABASE_DB_PASSWORD: Your supabase database password
SUPABASE_PROJECT_ID: Your supabase project id
SUPABASE_URL: Your supabase project URL
SUPABASE_ANON_KEY: Your supabase project anonymous key
POSTMARK_WEBHOOK_USER: User configured in Postmark to secure the webhook
POSTMARK_WEBHOOK_PASSWORD: Password configured in Postmark to secure the webhook
POSTMARK_WEBHOOK_AUTHORIZED_IPS: List of IPs (comma separated) authorized to send requests to the Postmark webhook
```

> **Note:** The `POSTMARK_*` variables are required for Atomic CRM's inbound email features. Have a look at the the [inbound email configuration](./inbound-email-configuration.md) to learn more about their usage and setup.
The GitHub action will run the `prod-deploy` command on every push to the `main` branch, deplyiong the frontend to GitHub pages and updating the Supabase instance.
Loading

0 comments on commit 46ef649

Please sign in to comment.