A comprehensive Point of Sale (POS) and Inventory Management system supporting dark/light modes and English/Chinese locales. Built with Nuxt3 on the frontend using TailwindCSS, Element-Plus, and Tabulator-table, and Python Django REST framework with Maria DB and Django ORM on the backend. Ensures database transactions adhere to ACID properties.
Project Framework Decision: Initially considered using Nitro (Nuxt3's default server-side server) but reverted to Django due to better ORM capabilities. Django ORM supports deep table joins required for sales summaries and inventory logs, which Prisma in Nitro could not efficiently handle.
Flexible Columns Handling: As different industries may have different columns in their product inventory. For example, the Jewelry Industry inventory may contain CTS and karat, while the Fashion Industry might include size, color, and material. Similarly, the Electronics Industry may have fields such as warranty_period, voltage, and brand. Besides migrate the Database structure each time, I design to use JSON to store the data as I still need to fit in Relational Database. First, I will extract all must required columns and a nullable json field as a product main table. And i will create a new table for storing the extra columns' name, type, isNullable etc. Then, I will use serializer to extract the json field from the product main table and convert it to structured json format based on the extra columns table data.
class ProductMain(models.Model):
# ...
extraData = models.JSONField(null=True, blank=True)
class ProductExtraDetails(models.Model):
field_name = models.CharField(max_length=255, unique=True)
field_label = models.CharField(max_length=255)
field_type = models.CharField(max_length=255) # Type : string , int, float, date
field_required = models.BooleanField(default=False)
class Meta:
db_table = "product_extra_details"
class ProductListSerializer(serializers.Serializer):
# ...
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
extra_fields = ProductExtraDetails.objects.all()
field_type_mapping = {
'char': serializers.CharField,
'float': serializers.FloatField,
'integer': serializers.IntegerField,
'boolean': serializers.BooleanField,
}
# Dynamically add the extra fields to the serializer
for extra_field in extra_fields:
field_class = field_type_mapping.get(
extra_field.field_type, serializers.CharField)
field_kwargs = {
'required': False,
'allow_null': True,
'allow_blank': True if extra_field.field_type == 'char' else None,
'max_length': 255 if extra_field.field_type == 'char' else None
}
self.fields[extra_field.field_name] = field_class(**field_kwargs)
def to_representation(self, instance):
representation = super().to_representation(instance)
extra_data = instance.extraData or {}
for key, value in extra_data.items():
if key in self.fields:
representation[key] = value
return representation
Middleware and Proxy Handling: Faced challenges in separating the server to Django, requiring the creation of middleware to handle proxy. Discovered that using a reverse proxy on Nuxt3 did not work in production builds. Manually created a reverse proxy server on Nitro to redirect APIs to the Django server. Managed complex authentication using Cookies and sessions to maintain auth data during proxying. Updated proxy code to support FormData for image and file uploads.
Dark Theme Stability: Did not encounter flickering issues with the dark theme in Nuxt3. Nuxt3 optimizes theme rendering by including color data in cookies, ensuring correct server-side rendering of themes. Seamless theme switching without visual glitches.
Hosting Challenges on Windows IIS: Encountered significant difficulties deploying the application on a Windows IIS server.
Issues Faced:
npx nuxi build --preset=iis_node, some required Node modules were missing. Resolved by manually copying node_modules from development to the server.Conclusion: While Vue3's component communication is excellent, Nuxt3 presents deployment and support challenges compared to Next.js.