This is the document I believe more teams need to write. How to develop a 'trivial' CRUD screen, in this case its the tasks part of our task management app.
This is a demonstration of the process documentation I describe .
In this document we will be building the entire tasks domain of our app, from database to Java API to React UI to Pull Request and finally Deployment.
I've focused on getting the steps right for now but will be expanding on what we are actually doing in each step in the future.
Prerequisites
.
Design
Process determines design because it will create a lot of the constraints the design needs to address. I'll work on this in the future when our process has stabilised.
Development
Checkout our specially made branch without any tasks.
git checkout no-tasks-do-not-merge
Open glue-stack in VSCode.
Open the terminal using (Control + `).
Follow the steps at , using the plus button in VSCode's terminal to create a new tab.
Take a look at the app without any tasks.
Database
Open Glue Stack in VSCode.
Start the database by opening a terminal (Control + `) and running:
docker-compose up
Task Table
The task table has a Many-To-One relationship to an organisation (just like the user table) and a Many-To-One relationship to a user. That means a task can be associated with a user and a user can have tasks associated with them.
Open sequel pro.
Connect to the docker database.
Click the plus on the bottom left. Name the table task with utf8mb4 encoding.
Add the organisation field.
The type of this column is going to match the type of the id of the organisation table. To keep things consistent all id columns are the same type.
A foreign key is a relational database constraint that means a particular field must match another field. In this case we're making sure the organisationId references an existing organisation.
Click the Relations tab.
Click the plus icon.
Name: (leave blank)
Column: organisationId
References
Table: organisation
Column: id
Click Add.
Click on the Structure tab again.
Click the plus icon in the middle of the page underneath the lone id Field to add a new field.
Field: name
Type: VARCHAR
Length: 255
Allow Null: false
Add the standard acive, createdDate, modifiedDate fields by running the following queries in the query tab.
ALTER TABLE `task` ADD `active` BIT(1) NOT NULL;
ALTER TABLE `task` ADD `createdDate` DATETIME NOT NULL;
ALTER TABLE `task` ADD `modifiedDate` DATETIME NOT NULL;
We've just created our new table so all we need to do now is add it to the codebase. If we added a few fields we could use the statement console (top right) and copy the relevant statements but this time we created a whole table so we can right click the table and select Copy Create Table Syntax.
Go back to VSCode.
Create a V2__task.sql at `api/src/main/resources/db/migration.
Paste your Create Table Syntax into the file. It should look like this:
Delete all your tables by selecting them and forcing deletion. This will let Flyway set them up from scratch using the scripts in the migration folder including your new scripts. (TODO: is there a better way?)
Open a new terminal tab.
Run the server.
cd api
mvn spring-boot:run
API
Entity
Create Task.java at `api/src/main/java/org/gluestack/api/domain/entity.
Stop the API using Control + c in its terminal window.
Start it again (using the up arrow to find the previously run command). This will validate that the entity we created matches the table in the database.
Commit your work.
Repository
Create the TaskRepository.java at `api/src/main/java/org/gluestack/api/repository.
Create the TaskService.java at `api/src/main/java/org/gluestack/api/service.
In this case the TaskService wants to return related entities to the user (the user details of the assigned user) so we use hibernate to load those details and the jackson-datatype-hibernate5 module will automatically serialise it (convert to JSON).
Our current test framework means you make it easy to reuse the test data you use in your tests so there is lest time wasted setting up the same data scenarios over and over again.
Open TestOrganisation.java.
Add a Task field called taskAssignedToActingUser.
Open TestOrganisationService.java and populate that test Task at the end of the create method.
Task taskAssignedToActingUser = new Task();
taskAssignedToActingUser.setName("Assigned Task");
taskAssignedToActingUser.setNotes("Assigned To Acting User");
taskAssignedToActingUser.setStatusId(1);
taskAssignedToActingUser.setUser(actingUser);
taskAssignedToActingUser.setOrganisation(organisation);
taskRepository.save(taskAssignedToActingUser);
testOrganisation.taskAssignedToActingUser = taskAssignedToActingUser;
Create FindAllTest.java at api/src/test/java/org/gluestack/api/task.
Put your cursor at the end of the word <Task, hit Control + Space and select the Task that says auto import (mine was the second option). It should add the following to the top of the file.
import { Task } from "./task";
Save.
Open sidebar/index.js using the same hotkey and technique as before.
Add the following below the "users" <ListItem in the render function.