This project explores what it means to combine Nx/Nextjs/Prisma/Graphql and Nexus auto code generation. It features Code first Schema Generation, with end-to-end type safety provided by Prisma and Nexus. This project highlights code splitting and sharing from NX workspaces and allows multiple web apps to consume a single graphql endpoint and render/edit/update data as they see fit.
This project also showcases how incredibly reusable tailwind is when you are looking for a consistent code quality for CSS.
I completed this project (part one and part two) in 5 hours.
Clone the project:
git clone [email protected]:Balance8/nx-challenge.git
Cd into the project:
cd nx-challenge
Install dependencies:
yarn
//or
npm install
create an .env file at the root with this variable:
DATABASE_URL="file:/tmp/todo-starter/todo.db"
Then run these commands:
yarn prisma db push
yarn nx run-many --target=serve --all --parallel
Then run:
yarn prisma studio
- This command will open up the Prisma studio window.
- Here, you will create a few new users under the user table.
- Once the users are created, you can create a new Ticket from the apps main menu and assign it to a user.
If you recieve an error, delete the dist folder as well as apps/api/src/generated/nexus.ts
& apps/api/src/generated/schema.graphql
Re-run yarn nx run-many --target=serve --all --parallel
To run tests, turn off your client and server and run the following command:
yarn nx run api:serve
Then in a new terminal:
yarn nx run next-app-e2e:e2e --no-exit
Make Sure you have the API running in the background or else the three tests will fail.
it('Create Ticket', function () {
/* ==== Generated with Cypress Studio ==== */
cy.visit('http://localhost:4200/');
cy.get('.mt-5 > :nth-child(1) > .flex').should('be.visible');
cy.get('.mt-5 > :nth-child(1) > .flex').click();
cy.get('.py-5').should('be.visible');
cy.get('#title').clear();
cy.get('#title').type('New Ticket');
cy.get('#user').select('1');
cy.get('#description').clear();
cy.get('#description').type('New Test');
cy.get('#completed').should('not.be.checked');
cy.get('.inline-flex').click();
/* ==== End Cypress Studio ==== */
});
/* ==== Test Created with Cypress Studio ==== */
it('Check Filter', function () {
/* ==== Generated with Cypress Studio ==== */
cy.get('.w-40 > .flex').click();
cy.get('.place-items-stretch > .grid > :nth-child(1)').click();
cy.get('.grid > :nth-child(4)').should(
'have.text',
'Task Status: Completed'
);
/* ==== End Cypress Studio ==== */
});
/* ==== Test Created with Cypress Studio ==== */
it('Edit Ticket', function () {
/* ==== Generated with Cypress Studio ==== */
cy.get('[href="/ticket/3"]').should('be.visible');
cy.get('[href="/ticket/3"]').click();
cy.get('.p-5').should('be.visible');
cy.get('.text-indigo-700').click();
cy.get('#user').select('1');
cy.get('#user').should('have.id', 'user');
cy.get('.inline-flex').click();
/* ==== End Cypress Studio ==== */
});
I would highly encourage a read into these blog posts about this topic:
and
- You will have to refresh the page to show any changes to the tickets, due to time constraints I did not implement any refetches or better cache control.
- Normally I would seed data for ease of use, due to time constraints I opted not to.