SyncSpace is a Notion-inspired course project built to practice full-stack web development, REST API design, relational data modeling, nested page structures, and interactive block editing.
The backend is powered by Spring Boot. The user interface is built with Thymeleaf, HTML, CSS, and vanilla JavaScript. User accounts, pages, and content blocks are stored in MySQL through Spring Data JPA, Hibernate, and JdbcTemplate.
This project was created for a university course. The repository contains the application source code and screenshots only; the local MySQL database and user data are not included.
- Register with a username, email address, and password
- Sign in with an email address and password
- Sign out of the current account
- Keep the user signed in after a page refresh
- Detect duplicate usernames and email addresses during registration
- Update the username after verifying the current password
- Update the email address after verifying the current password
- Change the password after entering the current password
- Manage account details through a tabbed settings dialog
- Create top-level pages
- Create child pages under an existing page
- Build page trees with unlimited nesting levels
- Display all pages in a hierarchical sidebar
- Expand and collapse child-page groups
- Rename a page by editing its main heading
- Display the current hierarchy as breadcrumbs
- Navigate to a parent page through the breadcrumbs
- Delete a page together with its child pages and blocks
- Convert a content block into a new child page
- Create a block with the
+button - Press Enter to quickly create the next block
- Edit text directly in the page
- Automatically save edited block content
- Delete an empty block with Backspace
- Use the following block types:
- Text (
p) - Heading 1 (
h1) - To-do (
todo) - Page link (
page)
- Text (
- Type
#to convert a block into Heading 1 - Type
[]to convert a block into a To-do item - Save the checked state of To-do blocks to the database
- Drag and drop blocks to rearrange them
- Automatically save the new order after dragging
- Duplicate an existing block
- Open a block context menu with a right click
- Use the context menu to:
- Turn into Text
- Turn into Heading 1
- Turn into To-do
- Turn into Page
- Duplicate
- Delete
- Switch between light and dark themes
- Save the theme preference in the browser
- Switch between English and Chinese
- Resize the sidebar by dragging its edge
- Save the sidebar width in the browser
- Navigate through an interactive page tree
- Use modal dialogs for page creation and account settings
- Preserve interface preferences with
localStorage
| Area | Technology |
|---|---|
| Language | Java 17 |
| Backend | Spring Boot |
| Web layer | Spring Web MVC and REST APIs |
| Templates | Thymeleaf |
| Frontend | HTML, CSS, and vanilla JavaScript |
| ORM | Spring Data JPA and Hibernate |
| SQL operations | JdbcTemplate |
| Database | MySQL |
| Build tool | Maven and Maven Wrapper |
| Development environment | Apache NetBeans |
flowchart LR
Browser["Browser UI<br/>Thymeleaf / HTML / CSS / JavaScript"]
Controller["Spring MVC Controllers<br/>REST APIs"]
Service["Service Layer"]
Repository["JPA Repositories<br/>JdbcTemplate"]
Database[("MySQL<br/>test")]
Browser -->|HTTP / JSON| Controller
Controller --> Service
Controller --> Repository
Service --> Repository
Repository --> Database
The application uses three main database tables. The database is created locally and its data is not committed to GitHub. A reusable schema is provided in database/schema.sql, while Hibernate can also update the schema from the application entities.
erDiagram
USERS ||--o{ PAGES : owns
PAGES ||--o{ PAGES : contains
PAGES ||--o{ BLOCKS : contains
USERS {
BIGINT id PK
VARCHAR username UK
VARCHAR email UK
VARCHAR password
}
PAGES {
BIGINT id PK
VARCHAR title
BIGINT user_id FK
BIGINT parent_page_id FK
}
BLOCKS {
BIGINT id PK
BIGINT page_id FK
VARCHAR block_type
VARCHAR content
INT sort_order
BOOLEAN is_checked
}
usersstores user accounts.pagesstores pages and usesparent_page_idas a self-reference for nested page trees.blocksstores page content, block types, display order, and To-do state.- JPA cascading removes child pages and blocks when their parent page is deleted.
- Block drag-and-drop ordering is saved by updating
sort_orderthrough JdbcTemplate.
Base URL:
http://localhost:8080
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/users/register |
Register a user |
POST |
/api/users/login |
Sign in |
PUT |
/api/users/{id}/username |
Update the username |
PUT |
/api/users/{id}/email |
Update the email address |
PUT |
/api/users/{id}/password |
Update the password |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/pages |
Create a top-level page or child page |
GET |
/api/pages/user/{userId} |
Get a user's top-level pages |
GET |
/api/pages/user/{userId}/all |
Get all pages belonging to a user |
PUT |
/api/pages/{id}/title |
Update a page title |
DELETE |
/api/pages/{id} |
Delete a page |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/blocks |
Create a block |
GET |
/api/blocks/page/{pageId} |
Get all blocks on a page |
PUT |
/api/blocks/{id} |
Update block content |
PUT |
/api/blocks/{id}/type |
Change the block type |
PUT |
/api/blocks/{id}/check |
Update a To-do block's checked state |
PUT |
/api/blocks/page/{pageId}/reorder |
Save the block order |
DELETE |
/api/blocks/{id} |
Delete a block |
- JDK 17
- MySQL
- Maven is optional because the Maven Wrapper is included
The recommended option is to import the included schema. It creates the test database and the users, pages, and blocks tables without inserting any sample data.
From a terminal with the MySQL client available:
mysql -u root -p < database/schema.sqlYou can also open phpMyAdmin, select Import, and choose database/schema.sql.
Alternatively, create only the database and allow Hibernate (spring.jpa.hibernate.ddl-auto=update) to create or update the tables:
CREATE DATABASE test
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;Update the connection settings for your local environment:
# src/main/resources/application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=On Windows:
.\mvnw.cmd spring-boot:runOn macOS or Linux:
./mvnw spring-boot:runOpen the application at:
http://localhost:8080/
src/
├── main/
│ ├── java/com/example/Final/
│ │ ├── controller/ # Web and REST API controllers
│ │ ├── entity/ # User, Page, and Block entities
│ │ ├── repository/ # JPA repositories and JdbcTemplate logic
│ │ └── service/ # User-related business logic
│ └── resources/
│ ├── static/ # CSS, JavaScript, translations, and images
│ ├── templates/ # Thymeleaf pages
│ └── application.properties
└── test/ # Spring Boot tests
database/
└── schema.sql # MySQL database and table definitions
This course project was developed to practice:
- Layered application design with Spring Boot MVC
- RESTful API design and JSON communication
- Spring Data JPA and Hibernate relationship mapping
- One-to-many and self-referencing relationships in MySQL
- Cascading deletion and nested data management
- Native SQL updates with JdbcTemplate
- DOM manipulation with vanilla JavaScript
- Drag-and-drop sorting, keyboard shortcuts, and context menus
- Browser state management with
localStorage - Multilingual interfaces and dark mode
- This repository contains source code and interface screenshots only.
- The local MySQL database and its user data are not included.
- Screenshot content is demonstration data created for the course project.


