Project developed for the course Advanced Software Construction Techniques held at Universidade do Porto (Engineering Faculty) by Professor João Pascoal Faria and Professor Jácome Cunha, a.y. 2025/26.
Local communities and the exchange of products and services are essential to strengthen resilience, reduce dependency on fragile global supply chains, and foster sustainable practices. By promoting reuse and circular economy principles, these networks extend product lifecycles, reduce waste, and make better use of available resources. In doing so, they empower the people, build social cohesion, and ensure quicker access to essential goods and services.
The goal of this assignment is to design and implement a family of applications that can be used by local communities to exchange products and services. You can think about it as an OLX-like application, but for small communities such as a neighbourhood, a school, the employees of a company, etc.
- Bianca Oliveira up202000139 - DSML + GUI + M2M transformation
- Filipe Cardoso up202006409 - GUI + M2T transformation
- François Morales up202503072 - structural metamodel + M2T transformation
- Guilherme Cruz up202403107 - GUI + M2M transformation
- Guilherme Martins up202403106 - report
- Hugo Silva 202403078 - DSML
- Irene Lo Presti up202502649 - structural metamodel + M2T transformation
For a detailed project organization, consult PROJECT_STRUCTURE.md.
models/- All models (DSML, generated)metamodels/- Original complete metamodelstransformations/- Transformation scripts(M2M e M2T)concrete-syntax/- Concrete syntax configuration (Blockly)ecore/- Ecore archives (EMF)docs/- Documentationimages/- Diagrams and Images
# DSML → GUI Model Refinado
python3 transformations/M2M/transform_dsml_to_gui.py
# DSML → Structural Model Refinado
python3 transformations/M2M/transform_dsml_to_structural.pycd transformations/M2T
python3 main.py-
Vinted
-
Facebook marketplace
-
Wallapop
-
Ebay
-
Superprof
-
OLX
| Concept | Intrinsic Properties | Extrinsic Properties |
|---|---|---|
| User | id: int, username: String, fullName: String, email: String, status: {beginner, intermediate, advanced}, joinDate: Date | 0..* Item, 0..* Service, 0..* Chat, 0..* Transaction, 0..* Bid |
| Item | id: int, name: String, price: float, description: String, Category: EnumCategory, condition: {New, LikeNew, Good, Fair}, brand: String, model: String, size: {XXS, XS, S, M, L, XL, XXL}, color: {Black, Red, White, Brown, Pink, Blue, Green, Grey, Purple}, quantity: int, category: {cloths, books, technology, lessons, house_works, pet-sitting, baby-sitting} | 1..1 User (owner), 0..1 Auction, 0..* Review, 0..1 Transaction |
| Service | id: int, name: String, priceType: {Fixed, Negotiable, Hourly, Free}, price: float, Category: {cloths, books, technology, lessons, house_works, pet-sitting, baby-sitting} | 1..1 User (owner), 0..1 Auction, 0..* Review, 0..1 Transaction |
| Chat | id: int, createdAt: Date | 2..2 User, 1..* Message |
| Message | id: int, sentAt: Date, text: String | 1..1 Chat |
| Auction | id: int, date: Date, finalPrice: float | 1..1 Item (or) 1..1 Service, 0..* Bid |
| Bid | id: int, amount: float, date: Date | 1..1 Auction, 1..1 User |
| Review | id: int, score: int, comment: String, timestamp: Date | 1..1 User (author), 1..1 Item OR 1..1 Service |
| Transaction | id: int, createdAt: Date, isPaid: bool, paymentMethod:{CashOnDelivery, Bank, Card} | 1..1 User (buyer), 1..1 Item/Service, 0..1 Shipment |
| Shipment | id: int, status: {Sent, InTransit, Failed, Delivered}, Address: String | 1..1 Transaction |
| Concept | Intrinsic Properties | Extrinsic Properties |
|---|---|---|
| Model | - | - |
| GUI Model | package: str, versionCode: str, versionName: str, description: str, screenCompatibility: bool | 0..* Module, 0..* ViewElement |
| NamedElement | name: str | - |
| Module | - | 1..1 GUI Model |
| ViewElement | description: str | 0..* ViewContainer, 0..* ViewComponent |
| Screen | id: int, name: str, x_dpi: str, y_dpi: str, screen_size: ScreenType, is_main_page: bool | 0..* ViewElement |
| ViewContainer | + attribute: str, + method() | 1..1 ViewElement, 0..* ViewComponent |
| ViewComponent | + attribute: str, + method() | 1..1 ViewElement |
| DataList | - | 1..* Class |
| List | - | 1..* ListItem |
| Tabs | selectedId: int | 1..* TabItem |
| Button | label: str, buttonType: ButtonType, actionType: ButtonActionType, targetScreen: Screen | - |
| Form | title: str | 0..* Input |
| Input | label: str, placeholder: str, type: InputFieldType, validationRules: str | 1..1 Form |
| Image | source: str | - |
| Card | title: str, subtitle: str, elevation: float, content: ViewComponent | 1..1 ViewComponent |
| AppBar | title: str | - |
| Spinner | type: SpinnerType, isLoading: bool | - |
| Class | - | 1..1 DataSource, 1..* Property |
| Property | - | 1..* DataSourceElement |
| DataSource | name: str | - |
| DataSourceElement | - | 1..1 DataSource |
| File | type: FileSourceType | - |
| Collection | type: CollectionSourceType | - |
| ListItem | label: str | 1..1 List |
| TabItem | id: int, label: str | 1..1 Tabs |
| Concept | Intrinsic Properties | Extrinsic Properties |
|---|---|---|
| CustomizationSpec | id: UUID, name: String, version: String, description: Text, createdAt: DateTime | 1..1 Feature (root), 0..* Policy, 0..* Rule |
| Feature | id: UUID, name: String, summary: String, optional: Boolean, abstract: Boolean, deprecated: Boolean | 0..* Feature (subFeatures/parent), 0..* FeatureGroup (groups/owner), 0..* FeatureParam |
| FeatureGroup | id: UUID, name: String, minSelect: int, maxSelect: int, ordered: Boolean | 1..1 Feature (owner), 2..* Feature (members) |
| FeatureParam | name: String, type: ValueType {Boolean, Integer, Decimal, String, Enum, Range}, required: Boolean, default: String, unit: String | 1..1 Feature, 0..* ParamOption |
| ParamOption | value: String, min: Decimal, max: Decimal, step: Decimal | 1..1 FeatureParam |
| Policy | id: UUID, type: PolicyType {REQUIRES, EXCLUDES, IMPLIES}, severity: Severity {Error, Warning, Info}, message: String, enabled: Boolean | 1..1 Feature (source), 1..1 Feature (target), 1..1 CustomizationSpec |
| Rule | id: UUID, language: ConstraintLanguage {OCL, Propositional, Regex, Other}, expr: Text | 0..* Feature (scope), 1..1 CustomizationSpec |
| Configuration | id: UUID, name: String, createdBy: String, createdAt: DateTime | 0..* Selection, 0..* ParamBinding |
| Selection | selected: Boolean | 1..1 Feature, 1..1 Configuration |
| ParamBinding | value: String | 1..1 FeatureParam, 0..1 Feature (ofFeature), 1..1 Configuration |