Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
87db0ea
chore: start nx migration
jmclellan-crexi Apr 6, 2026
040214a
chore: [nx migration] remove-legacy-cache
jmclellan-crexi Apr 6, 2026
e7d7b42
chore: [nx migration] 21-1-0-add-ignore-entries-for-nx-rule-files
jmclellan-crexi Apr 6, 2026
25d9e5f
chore: [nx migration] rename-test-path-pattern
jmclellan-crexi Apr 6, 2026
cd5d3c9
chore: [nx migration] update-angular-cli-version-19-2-0
jmclellan-crexi Apr 6, 2026
bbc9de5
chore: [nx migration] set-continuous-option
jmclellan-crexi Apr 6, 2026
8652500
chore: [nx migration] update-angular-cli-version-20-0-0
jmclellan-crexi Apr 6, 2026
0e54788
chore: [nx migration] migrate-provide-server-rendering-import
jmclellan-crexi Apr 6, 2026
7279145
chore: [nx migration] set-generator-defaults-for-previous-style-guide
jmclellan-crexi Apr 6, 2026
4fa396c
chore: [nx migration] update-module-resolution
jmclellan-crexi Apr 6, 2026
91e0152
chore: [nx migration] update-angular-cli-version-20-1-0
jmclellan-crexi Apr 6, 2026
6be0cc9
chore: [nx migration] set-tsconfig-option
jmclellan-crexi Apr 6, 2026
2de76f8
chore: [nx migration] update-angular-cli-version-20-2-0
jmclellan-crexi Apr 6, 2026
c06e720
chore: [nx migration] update-angular-cli-version-20-3-0
jmclellan-crexi Apr 6, 2026
f7f3768
chore: [nx migration] add-bootstrap-context-to-server-main
jmclellan-crexi Apr 6, 2026
61b1533
chore: start nx migration
jmclellan-crexi Apr 6, 2026
f1e860a
chore: [nx migration] 22-6-1-add-claude-worktrees-to-git-ignore
jmclellan-crexi Apr 6, 2026
0da2a17
chore: [nx migration] 22-6-0-add-claude-settings-local-to-git-ignore
jmclellan-crexi Apr 6, 2026
b3cdd47
chore: [nx migration] update-module-resolution-22-2-0
jmclellan-crexi Apr 6, 2026
2507d25
chore: [nx migration] update-typescript-lib-22-2-0
jmclellan-crexi Apr 6, 2026
6059b63
chore: [nx migration] set-isolated-modules-22-3-0
jmclellan-crexi Apr 6, 2026
be2a3b0
chore: [nx migration] bootstrap-options-migration
jmclellan-crexi Apr 6, 2026
c9d628b
migrate to pnpm
jmclellan-crexi Apr 6, 2026
8b96583
chore: restructure apps, migrate to vitest, enable zoneless, pin deps
jmclellan-crexi Apr 6, 2026
4401a24
fix: import defineConfig from vitest/config to resolve type mismatch
jmclellan-crexi Apr 6, 2026
f223279
add start script and update readme
jmclellan-crexi Apr 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ jobs:
# - run: npx nx-cloud start-ci-run --distribute-on="3 linux-medium-js" --stop-agents-after="e2e-ci"

# Cache node_modules
- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
cache: 'pnpm'

- run: npm ci
- run: pnpm install --frozen-lockfile
- run: npx playwright install --with-deps
- uses: nrwl/nx-set-shas@v4

Expand Down
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ node_modules
/libpeerconnection.log
npm-debug.log
yarn-error.log
pnpm-debug.log
testem.log
/typings

Expand All @@ -43,3 +44,10 @@ Thumbs.db
migrations.json

.angular
.cursor/rules/nx-rules.mdc
.github/instructions/nx.instructions.md

.claude/worktrees
.claude/settings.local.json
# SQLite
*.db
20 changes: 20 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Debug api with Nx",
"runtimeExecutable": "pnpm exec",
"runtimeArgs": ["nx", "serve", "api"],
"env": {
"NODE_OPTIONS": "--inspect=9229"
},
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"skipFiles": ["<node_internals>/**"],
"sourceMaps": true,
"outFiles": ["${workspaceFolder}/apps/api/dist/**/*.(m|c|)js", "!**/node_modules/**"]
}
]
}
96 changes: 70 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,86 @@
# AngularTask
# Crexi Full-Stack Interview

## Goal

The goal of this assignment is to showcase your skills and coding style while building an enterprise grade Angular application. You may take your time with this assessment to show case your skills. Once you have it working you can add some extra flare with unit testing, e2e testing with playwright, updated styles to make it snazzy, or whatever else you feel like.
Build a full-stack TypeScript application using **NestJS**, **Angular**, and **Drizzle ORM** with SQLite. The application is a commercial real estate property search platform that demonstrates proficiency across the entire stack.

> [!TIP]
### Evaluation Criteria

- **Feature Completion** — Did you deliver working functionality for each task? We're looking at whether the features meet the requirements, handle edge cases, and work end-to-end across the stack.
- **Code Quality & Best Practices** — Is the code clean, well-structured, and maintainable? We evaluate adherence to Angular/NestJS conventions, proper typing, separation of concerns, component design, error handling, and consistent patterns throughout the codebase.
- **AI Usage** — We encourage you to use AI tools. We want to see **how** you use them — the prompts you write, the skills you leverage, and how you orchestrate AI assistance to be productive. Treat AI as a tool in your workflow and show us your ability to direct it effectively.
- **Thought Process** — How do you break down problems and direct AI to solve them? We're looking at how you decompose tasks, sequence your prompts, and course-correct when output isn't right.

## Tech Stack

| Layer | Technology |
| ----------- | ----------------------------------- |
| Frontend | Angular, Angular Material, Tailwind |
| Backend | NestJS |
| ORM | Drizzle ORM |
| Database | SQLite (via better-sqlite3) |
| Monorepo | Nx |
| State Mgmt | NgRx (optional) |

> [!TIP]
> **State Management** - We have included all of the `@ngrx` packages but you're welcome to use any state management library you see fit or just stateful services.
>
>
> **Component Library** - We have included [@angular/material](https://material.angular.io/components/categories) but you're welcome to use any component library that suites your needs. Ex: [PrimeNG](https://primeng.org/installation)
>
>
> **Styling** - We have included [tailwindcss](https://tailwindcss.com/docs/styling-with-utility-classes) but you can style using scss, or css directly if you prefer.

## Getting Started

> [!CAUTION]
> **DO NOT FORK THIS REPO** - Instead click the [Download Zip](https://github.com/crexi-dev/angular/archive/refs/heads/main.zip).
Run `pnpm start` to install dependencies, push the database schema, and serve the full stack in one step.

- Install packages with `npm i`
- Serve the application using `npx nx run angular-task:serve`
- You're off to the races coding! Good luck!
- API is available at `http://localhost:3000/api`
- Web app is available at `http://localhost:4200`

## Useful NX tips and tricks
> [!TIP]
> **NX Generators** - you're more than welcome to modify the [NX Generators](https://nx.dev/reference/nx-json#generators) section inside of the `nx.json` file with any changes you prefer for your setup.
- [@nx/angular:component Documentation](https://nx.dev/nx-api/angular/generators/component) Create an angular component using `npx nx g @nx/angular:component`
- Create an angular service using `npx nx g @nx/angular:service`
- [@nx/angular:pipe Documentation](https://nx.dev/nx-api/angular/generators/pipe) Create an angular pipe using `npx nx g @nx/angular:pipe`
- [@nx/angular:directive Documentation](https://nx.dev/nx-api/angular/generators/directive) Create an angular directive using `npx nx g @nx/angular:directive`
- [@nx/angular:library Documentation](https://nx.dev/nx-api/angular/generators/library) Create an angular library using `npx nx g @nx/angular:library`
Or run each step manually:

- Install packages with `pnpm install`
- Push the database schema with `pnpm exec drizzle-kit push --config=apps/api/drizzle.config.ts`
- Serve the full stack with `pnpm nx serve web` (automatically starts the API)

## User Management Application
## Tasks

1. Home page should show a card view of users from [JSONplaceholder](https://jsonplaceholder.typicode.com/). The home page should allow you to click on a users card to navigate to their profile page.
2. The profile page should use the angular router and exist at `/users/:id` and display all of the user information for the id in the route path.
3. Add filter(s) to the home page to allow the user to filter the list.
4. Add a way to favorite users in both the card view and detail page.
5. Run the following command to verify that your changes lint, test, and build correctly: `npx nx affected -t lint test build`.
### 1. Property Search Page
Build a property search page that displays commercial real estate listings in a card-based layout. Each card should show basic property information such as name, address, price, property type, and a thumbnail image. Clicking a card should navigate to the property detail page.

## Submitting your Assessment
### 2. Property Detail Page
Create a property detail page at `/properties/:id` that displays comprehensive information about a single property including full description, location details, financials, property specs, and image gallery.

### 3. Sorting, Filtering & Pagination
Enhance the property search page with:
- **Sorting** by price, name, date listed, etc.
- **Filtering** by property type, price range, location, etc.
- **Pagination** to handle large result sets efficiently (server-side)

### 4. Property Chat Bot Widget
Add an AI-powered chat bot widget to the property detail page that allows users to ask questions and get more information about the property they are viewing.

## Useful Commands

| Command | Description |
| --- | --- |
| `pnpm nx serve web` | Serve the full stack (web + api) |
| `pnpm nx serve api` | Serve just the API |
| `pnpm nx build web` | Build the web app |
| `pnpm nx build api` | Build the API |
| `pnpm nx test web` | Run web unit tests |
| `pnpm nx lint web` | Lint the web app |
| `pnpm nx affected -t lint test build` | Run affected lint, test, and build |
| `pnpm exec drizzle-kit generate --config=apps/api/drizzle.config.ts` | Generate a migration |
| `pnpm exec drizzle-kit push --config=apps/api/drizzle.config.ts` | Push schema to DB |
| `pnpm exec drizzle-kit studio --config=apps/api/drizzle.config.ts` | Open Drizzle Studio |

## NX Tips

> [!TIP]
> **NX Generators** - you're more than welcome to modify the [NX Generators](https://nx.dev/reference/nx-json#generators) section inside of the `nx.json` file with any changes you prefer for your setup.

Please submit a link to your public github repo and approximately how long it took you to complete this task. We will have a panel to discuss your desicions and design patterns.
- [@nx/angular:component](https://nx.dev/nx-api/angular/generators/component) - `pnpm nx g @nx/angular:component`
- [@nx/angular:service](https://nx.dev/nx-api/angular/generators/service) - `pnpm nx g @nx/angular:service`
- [@nx/angular:pipe](https://nx.dev/nx-api/angular/generators/pipe) - `pnpm nx g @nx/angular:pipe`
- [@nx/angular:directive](https://nx.dev/nx-api/angular/generators/directive) - `pnpm nx g @nx/angular:directive`
- [@nx/angular:library](https://nx.dev/nx-api/angular/generators/library) - `pnpm nx g @nx/angular:library`
9 changes: 0 additions & 9 deletions apps/angular-task-e2e/project.json

This file was deleted.

22 changes: 0 additions & 22 deletions apps/angular-task/jest.config.ts

This file was deleted.

95 changes: 0 additions & 95 deletions apps/angular-task/project.json

This file was deleted.

3 changes: 0 additions & 3 deletions apps/angular-task/src/app/app.component.html

This file was deleted.

7 changes: 0 additions & 7 deletions apps/angular-task/src/main.server.ts

This file was deleted.

3 changes: 0 additions & 3 deletions apps/angular-task/src/test-setup.ts

This file was deleted.

11 changes: 0 additions & 11 deletions apps/angular-task/tsconfig.spec.json

This file was deleted.

13 changes: 13 additions & 0 deletions apps/api/drizzle.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { defineConfig } from 'drizzle-kit';
import { resolve } from 'path';

const apiDir = __dirname;

export default defineConfig({
schema: resolve(apiDir, 'src/db/schema.ts'),
out: resolve(apiDir, 'drizzle'),
dialect: 'sqlite',
dbCredentials: {
url: resolve(apiDir, 'sqlite.db'),
},
});
8 changes: 8 additions & 0 deletions apps/api/drizzle/0000_faulty_surge.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CREATE TABLE `users` (
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
`name` text NOT NULL,
`email` text NOT NULL,
`created_at` integer NOT NULL
);
--> statement-breakpoint
CREATE UNIQUE INDEX `users_email_unique` ON `users` (`email`);
Loading
Loading