The Plant Tracker API will allow users to manage and track their plants through different growth stages. Built with Node.js, Express.js, and MongoDB, the API will store plant data such as growth stages, start dates, and projected harvest dates. Users will be able to update plant stages, archive or delete plants, and retrieve plant information via a RESTful API. The application will be containerized with Docker for easy deployment and scalability, with Nginx acting as a reverse proxy to ensure secure and efficient traffic routing.
Planned future enhancements include a CLI client, a web GUI (likely in React), and incorporating notifications for plant care reminders among others
Tech Stack
- Node.js & Express.js: Together, they power the backend API, with Node.js handling asynchronous, event-driven tasks and Express providing a lightweight framework for routing and middleware integration.
- MongoDB: A NoSQL database for storing plant data, offering flexibility and scalability in managing unstructured data.
- Docker: Containerizes the application, ensuring consistent environments and simplifying deployment with Docker Compose to manage multiple services.
- Nginx: Serves as a reverse proxy, improving security, load balancing, and overall scalability of the application.
Features
-
Tracks the following information per plant:
- Name
- Plant ID (auto-generated if not provided)
- Source (seed or clone)
- Projected harvest date (auto-calculated and updated with each stage change)
- Start date (date of sprouting)
- Start date of vegetative phase
- Start date of flowering phase
- Harvest date
- Start date of cure phase
- Current stage (seedling, vegetative, flowering, harvested, curing)
-
Automatically generates unique plant IDs if not provid
Plant Schema
Property: | Type: | Notes: |
---|---|---|
name | string | Required |
plantAbbr | string | Auto-generated |
status | active |archived |inactive |
See below |
source | seed |clone |
|
stage | seedling |veg |flower |harvested |cure |
|
notes | string | |
startedOn | date (YYYY-MM-DD) | |
vegStartedOn | date (YYYY-MM-DD) | |
flowerStartedOn | date (YYYY-MM-DD) | |
potentialHarvest | date (YYYY-MM-DD) | Read-only |
harvestedOn | date (YYYY-MM-DD) | |
cureStartedOn | date (YYYY-MM-DD) |
- Archived and inactive plants are hidden by default.
- Inactive plants are plants that have been “deleted” through the API. They are only marked as inactive so they can be “undeleted” if necessary.
Create a new plant
POST /api/v1/plants
Valid POST
request parameters
Field: | Type: | Notes: |
---|---|---|
name | string | Required |
source | seed |clone |
Defaults to seed |
stage | seedling |veg |flower |harvested |cure |
Defaults to seedling |
notes | string | |
startedOn | date (YYYY-MM-DD) | Defaults to today |
vegStartedOn | date (YYYY-MM-DD) | Must be > startedOn and < flowerStartedOn |
flowerStartedOn | date (YYYY-MM-DD) | Must be > vegStartedOn |
If the plant is a clone, stage will default to veg
and vegStartedOn
be set to the value of startedOn
Possible POST
responses
HTTP 201
Successfully created plant. Response contains the newly-created plant. For example:
{
"_id": "662849f8b87798f29434dc23",
"status": "active",
"source": "seed",
"name": "Roma Tomato 1",
"stage": "veg",
"startedOn": "2024-04-23T00:00:00.000+00:00",
"potentialHarvest": "2024-06-25T00:00:00.000+00:00",
"plantAbbr": "RT1-1",
"createdAt": "2024-04-23T23:53:28.245+00:00",
"updatedAt": "2024-04-24T12:39:59.743+00:00",
"vegStartedOn": "2024-04-23T00:00:00.000+00:00"
}
HTTP 409
An active plant with the same name already exists. See API Errors below.
HTTP 500
An unrecoverable error occurred. See API Errors below.
Get all plants
GET /api/v1/plants
List of plants will be filtered by any request parameters provided.
Valid GET /api/v1/plants
request parameters
Field: | Type: | Notes: |
---|---|---|
status | active |archived |inactive |
Defaults to ‘active’ |
name | string | |
stage | seedling |veg |flower |harvested |cure |
|
startedOn | date (YYYY-MM-DD) | |
vegStartedOn | date (YYYY-MM-DD) | |
flowerStartedOn | date (YYYY-MM-DD) | |
harvestedOn | date (YYYY-MM-DD) | |
cureStartedOn | date (YYYY-MM-DD) | |
archivedOn | date (YYYY-MM-DD) |
Possible GET /api/v1/plants
responses
HTTP 200
Successfully found plants. Contains array of matching plant objects in response body. For example:
[
{
"_id": "662849f8b87798f29434dc23",
"status": "active",
"source": "seed",
"name": "Roma Tomato 1",
"stage": "veg",
"startedOn": "2024-04-23T00:00:00.000+00:00",
"potentialHarvest": "2024-06-25T00:00:00.000+00:00",
"plantAbbr": "RT1-1",
"createdAt": "2024-04-23T23:53:28.245+00:00",
"updatedAt": "2024-04-24T12:39:59.743+00:00",
"vegStartedOn": "2024-04-23T00:00:00.000+00:00"
},
{
"_id": "98f29434dc23662849f8b877",
"status": "active",
"source": "seed",
"name": "Cherry Tomato 1",
"stage": "veg",
"startedOn": "2024-04-23T00:00:00.000+00:00",
"potentialHarvest": "2024-06-25T00:00:00.000+00:00",
"plantAbbr": "CT1-1",
"createdAt": "2024-04-23T23:53:28.245+00:00",
"updatedAt": "2024-04-24T12:39:59.743+00:00",
"vegStartedOn": "2024-04-23T00:00:00.000+00:00"
},
...
]
HTTP 404
No plants found matching the request data provided. See API Errors below.
HTTP 500
An unrecoverable error occurred. See API Errors below.
Get a particular plant
GET /api/v1/plants/{plantId}
Valid GET /api/v1/plants/{plantId}
request parameters
See valid request parameters for GET /api/v1/plants
above.
Possible GET /api/v1/plants/{plantId}
responses
HTTP 200
Successfully found plant. Contains found plant object in response body. For example:
{
"_id": "662849f8b87798f29434dc23",
"status": "active",
"source": "seed",
"name": "Roma Tomato 1",
"stage": "veg",
"startedOn": "2024-04-23T00:00:00.000+00:00",
"potentialHarvest": "2024-06-25T00:00:00.000+00:00",
"plantAbbr": "RT1-1",
"createdAt": "2024-04-23T23:53:28.245+00:00",
"updatedAt": "2024-04-24T12:39:59.743+00:00",
"vegStartedOn": "2024-04-23T00:00:00.000+00:00"
}
HTTP 404
Plant not found. See API Errors below.
HTTP 500
An unrecoverable error occurred. See API Errors below.
Update a plant
PUT /api/v1/plants/{plantId}
Valid HTTP request parameters
Field: | Type: | Notes: |
---|---|---|
name | string | |
source | seed |clone |
|
stage | seedling |veg |flower |harvested |cure |
See notes below* |
notes | string | |
startedOn | date (YYYY-MM-DD) | Must be <= vegStartedOn |
vegStartedOn | date (YYYY-MM-DD) | Must be >= startedOn and < flowerStartedOn |
flowerStartedOn | date (YYYY-MM-DD) | Must be > vegStartedOn and < harvestedOn |
harvestedOn | date (YYYY-MM-DD) | Must be > harvestedOn and < cureStartedOn |
cureStartedOn | date (YYYY-MM-DD) | Must be > harvestedOn |
*If the plant stage changes, the dates will be updated accordingly. For example:
- If the plant stage is changing from
flower
toveg
,flowerStartedOn
will be unset andveg
will be set to today (unless provided in the request parameters). - If the plant stage is changing from
veg
toflower
,flowerStartedOn
is set to today
Possible PUT
responses
HTTP 200
Successfully updated plant. Contains the updated plant in body. For example:
{
"_id": "662849f8b87798f29434dc23",
"status": "active",
"source": "seed",
"name": "Roma Tomato 1",
"stage": "veg",
"startedOn": "2024-04-23T00:00:00.000+00:00",
"potentialHarvest": "2024-06-25T00:00:00.000+00:00",
"plantAbbr": "RT1-1",
"createdAt": "2024-04-23T23:53:28.245+00:00",
"updatedAt": "2024-04-24T12:39:59.743+00:00",
"vegStartedOn": "2024-04-23T00:00:00.000+00:00"
}
HTTP 404
Plant not found. See API Errors below.
HTTP 409
An active plant with the same name already exists. See API Errors below.
HTTP 500
An unrecoverable error occurred. See API Errors below.
Examples
To move a plant from seedling
to veg
, send the following to PUT /api/v1/plants/{plantId}
:
{
"stage": "veg"
}
To move a plant from seedling
to veg
and set the start date to '2024-04-20'
, send a PUT
request to /api/v1/plants/{plantId}
with the following request parameters:
{
"stage": "veg",
"vegStartedOn": "2024-04-20"
}
To rename a plant from 'Tomato Plant 1'
to 'Roma Tomato Plant 1'
, send a PUT
request to /api/v1/plants/{plantId}
with the following request parameters:
{
"name": "Roma Tomato Plant 1"
}
Delete a plant
DELETE /api/v1/plants/{plantId}
Possible responses:
HTTP 204
if successfulHTTP 500
if an error occurred (see API Errors below)
API Errors
If an error occurs, a response will be returned with the error message in the body. For example:
{ "error": "Something bad happened." }
Completeness level
-
Creating Plants:
- Basic functionality
- Auto-generate
plantAbbr
- Add log entry when creating plant
- Validate plant before creation (see Validation section below)
- Set
vegStartedOn
=startedOn
ifsource
=="clone"
-
Modifying Plants:
- Basic functionality
- Regenerate
plantAbbr
if name changed - Update dates when changing status
- Set “started on” dates to current date unless provided
- Unset “started on” dates that occur after current stage
- Add log entry when updating plant
- Set
vegStartedOn
=startedOn
ifsource
=="clone"
- Validate plant before updating (see Validation section below)
- Add ability to update multiple plants at once
- Add ability to mark plants as dead
-
Listing Plants:
- Basic functionality
- Filter based on request parameters
- Filter based on plant status
-
Deleting Plants:
- Basic functionality
- Add log entry when deleting plant
-
Archiving Plants:
- Basic functionality
- Add log entry when archiving plant
-
Validation:
- Set required dates based on plant stage
- Check plant name for characters outside letters, numbers, and punctuation
- Add support for emoji in plant name
- Check plantAbbr for characters outside
a–z
,A–Z
,0–9
and-
- Validate stage start dates in relation to each other
-
Authentication:
- Implement OAauth and JWT-based authentication for API
- Implement password-based authentication for GUI
-
Plant Journal:
- Add support for plant journal entries
- Add ability to delete journal entries
Other Planned Features
-
Frontend GUI:
- Implement frontend GUI
- Plants:
- Add ability to create plants
- Add ability to view plants
- Add ability to edit plants
- Add ability to delete plants
- Add ability to move plants between stages
- Add ability to mark plant as dead
- Plant Journal:
- Add ability to add plant journal entries
- Add ability to edit plant journal entries
- Add ability to delete plant journal entries
- Plants:
- Implement frontend GUI