agile – Effectively running large front-end platform with multiple teams contributing

I work at a company where we have built much of our own e-commerce platform from the ground up. We have a growing number of teams who effectively operate as stream-aligned teams, based on functional areas (Growing x capability, improving customer retention, etc etc). We have 10-15 teams containing a Product owner, delivery manager, business analyst, software dev in test, and engineers to give an idea for the size of the engineering department.

Our estate is made up of a number of large services built by the teams to meet the needs of the business. We have a target architecture within the business, however, the teams are given a lot of autonomy as to how they would like to work within this architecture and which tools they want to use. This works really effectively in the majority of cases – bar one area.

Our front-end platform, which is a mono-repo React application, is a large and growing project that houses the business’s front-end website. This project is contributed to by a number of different stream-aligned teams, who may not be working even within the same functional area. An example being one team working on my account feature, whilst others work on an improved search capability.

The project is version controlled via GIT and has a working pipeline with volatile environments for feature branches to allow for testing. Our teams all operate using either scrum or kanban and we do our best to invest in agile practices.

The issue we are having is this project does not have a clear owner, and is rapidly growing in complexity and diverging in standards of code, approach to e2e testing, etc. This is having an impact on our ability to release frequently and with confidence, as we are now frequently having issues.

I think Conway’s law is playing a large part in this, but it would be really interesting to see how others have managed this problem (open-source projects could be a good inspiration for a model we could use potentially).

I’d appreciate any suggestions for patterns or practices we can implement to better manage this repo. The engineering department has grown quite rapidly over the last two years, so some mistakes have been made along the way and I’m keen to address them.
Thanks for reading my question!

How can I effectively model a property in a relational database?

I have seen two approaches to modeling properties in relational databases:

  1. Create arbitrary tables that assume all the necessary components of the property. For example, have tables for room, unit, floor, building.

  2. Have a single table ‘asset’. Use a linking table to create relations between assets.

In either case, the building is represented as a general tree structure. This seems painful to query.

I need to represent this tree in order to implement an RBAC system. Now I’m not so sure that a relational DB is the best solution.

Does the higher-leve testing mentioned in the book Working Effectively with Legacy Code belong to integration test?

  1. is higher-level testing a standard term in software engineering?

No, I don’t think so. It is just a description, which distinguishes those tests from unit tests in the specific context of the book chapter where you found it.

  1. does higher-level testing belong to the integration test as it pins down behavior for a set of classes?

To my understanding, it is the other way round: the term “integration test”, when used in opposition to unit tests, can be seen as one kind of “higher-level” tests (among other types of tests).

database – How to effectively sperate CRUD operations from the main SQLiteOpenHelper – android studio

I’m conflicting about how I want my database architecture to be built.
First of all, I use a singleton pattern for the database in order to insure one instance of it (so its thread-safe), and also for me to get a workable database reference wherever I have a context.

All across the application I make many different db operations, for example, some activities need to change only the ‘Meals’ table and some need to change ‘Meals’ & ‘MealFoods’ for example.

For each one of this tables I’ve built a helper class in order to separate the CRUD operations of each table apart from the DatabaseManager class (which extends SQLiteOpenHelper). This, of course is for the sake of simplicity and to get a cleaner code.

First approach:

This approach saves all the helper classes inside the DatabaseManager.

DatabaseManager.java:

public class DatabaseManager extends SQLiteOpenHelper {
    private static String dbName = "logs.db";
    private static final int dbVersion = 1;

    private final Context context;
    public MealsDBHelper mealsDBHelper;
    public MealFoodsDBHelper mealFoodsDBHelper;

    private DatabaseManager(@NonNull Context context) {
        super(context, dbName, null, dbVersio);
        this.context = context.getApplicationContext();//Saving as application context to avoid leaks
        mealsDBHelper = new MealsDBHelper(context);
        mealFoodsDBHelper = new MealFoodsDBHelper(context);
    }

    private static DatabaseManager instance;
    public static synchronized DatabaseManager getInstance(Context context) {
        if (instance == null) {
            instance = new DatabaseManager(context);
        }
        return instance;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        //...
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //...
    }
}

Let’s look at the MealsDBHelper class, which pretty much all it does is to help communicate CRUD operations with the database. (For example a user wants to change his meal name)

public class MealsDBHelper {
    public static final String MEALS_TABLE_NAME = "Meals";
    public static final String MEAL_ID_COLUMN = "Meal_ID";
    public static final String MEAL_NAME_COLUMN = "Meal_Name";
    public static final String MEAL_POS_COLUMN = "Meal_Pos";
    public static final String MEAL_DATE_COLUMN = "Date";


    private Context context; //A context object to pass on to the DatabaseManager.getInstance method in all the different methods inside this class
    public MealsDBHelper(Context context){
        this.context = context;
    }

    //For example one of few methods that do operations on the 'Meals' table in the database.
    public void updateMealName(long mealId, String meal_name) {
        UserDataDB.getInstance(context).getWritableDatabase().execSQL("UPDATE " + MEALS_TABLE_NAME + " SET " + MEAL_NAME_COLUMN + " = '" + meal_name + "' WHERE " + MEAL_ID_COLUMN + " = " + mealId);
    }
}

Now, no matter if the activity is modifying 1 or 2 or even 3 tables, I’m able to update the meal’s name like so:

DatabaseManager.getInstance(context).mealsDBHelper.updateMealName(mealId, mealName);

Thats because the DatabaseManager contains a reference to all the other helper classes.

What I like about this approach is that I can simply access every table and do operations on it according to my needs, & what I don’t like is that the DatabaseManager class holds reference for all the helpers, and I’m not sure if its best to do so..

Second approach:

This approach does not saves all the helper classes inside the DatabaseManager.

DatabaseManager.java:

public class DatabaseManager extends SQLiteOpenHelper {
    private static String dbName = "logs.db";
    private static final int dbVersion = 1;

    private final Context context;

    private DatabaseManager(@NonNull Context context) {
        super(context, dbName, null, dbVersio);
        this.context = context.getApplicationContext();//Saving as application context to avoid leaks
    }

    private static DatabaseManager instance;
    public static synchronized DatabaseManager getInstance(Context context) {
        if (instance == null) {
            instance = new DatabaseManager(context);
        }
        return instance;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        //...
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //...
    }
}

Now, if my activity needs to modify both ‘Meals’ & ‘MealFoods’ tables I can construct the helpers in onCreate, such as:

public class AddFoodActivity extends AppCompatActivity{

    MealsDBHelper mealsDBHelper;
    MealFoodsDBHelper mealFoodsDBHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(..);

        mealsDBHelper = new MealsDBHelper(this);
        mealFoodsDBHelper = new MealFoodsDBHelper(this);
    }

    //Then whenever I need to modify the table I use:
    mealsDBHelper.updateMealName(mealId, mealName);
}

What I like about this approach is that I can use a simple line to modify a table according to my needs,
& what I don’t like is that I need to define helper references for every activity, and it kind of makes the code inconsistent.

Basically are there any downsides for using one of the methods?

I’ll admit I did leave a big chunk of code out of this post, but its only because I think it won’t add a lot to your understanding of the problem, because its a more general one.

Thank you very much for any kind of help.

dnd 5e – Is a Wild Shaped druid effectively immune to the Detect Thoughts spell?

RAW, if a form’s Languages section is blank, that form is immune to detect thoughts.

This is the rules as written ruling. A druid wildshaped into a wolf cannot speak any languages, so detect thoughts does not apply, as detect thoughts says:

You can’t detect a creature with an Intelligence of 3 or lower or one that doesn’t speak any language.

As for telepathy, it probably depends on the wording of the particular feature granting telepathy. If I’m DMing, it doesn’t matter because…

Some beasts have a language, which may still protect them from detect thoughts.

For example, the Giant Elk:

Languages Giant Elk , understands Common, Elvish, and Sylvan but can’t speak them

So our druid uses Wildshape to become a Giant Elk. Now they can speak the Giant Elk language.

This means they can think in Giant Elk.

If the caster of detect thoughts does not themselves speak Giant Elk, then they wouldn’t be able to understand the thoughts of the druid.

Of note, the answer in this Q&A argues to the contrary, so it would not be unreasonable for a DM to rule that thinking in Giant Elk doesn’t help.

I would rule that the druid is not immune to detect thoughts.

This is a situation where I would rule against the RAW ruling. Wildshape has this feature:

you retain your alignment, personality, and Intelligence, Wisdom, and Charisma scores.

Despite taking the form of a Beast, you retain all of your mental ability scores – you are still just as wise and intelligent as you were in your normal form. To me, this means that a druid wildshaped into a bear does not think like a bear, rather thinks just as they did in their normal form. I would rule that you still think in whatever language you usually think in, so are still vulnerable to detect thoughts (unless you think in a language the caster does not know).

differential equations – Step size is effectively zero

I’ve been trying to solve Bodewadt flow equations which is a system of differential equations.

F² – G² + HF’ – F”+1 = 0

2GF + HG’-G” = 0

2F + H’ = 0

Boundary conditions:

F(0)=G(0)=H(0)=0

F(∞)=0,G(∞)=1

I turned them into a system of first order ordinary differential equations where F=x;F’=y;G=z,G’=s and H=p. Thing is, I don’t have the derivatives F'(0) and G'(0) so I should make use of boundary conditions in infinite, instead, I use a sufficiently large number instead of infinite, aproximately “14” works fine.

sol = {x(t), y(t), z(t), s(t), p(t)} /.
NDSolve({x'(t) == y(t), y'(t) == x(t)^2 - z(t)^2 + s(t) y(t) + 1, 
s'(t) == 2 z(t) x(t) + p(t) s(t), z'(t) == s(t), p'(t) == -2 x(t),
 x(0) == 0, z(0) == 0, p(0) == 0, x(14) == 0, z(14) == 1}, {x, y, 
z, s, p}, {t, 0, 14})

The problem is that when I run the code I have the next problem:

NDSolve: At t == 3.4508216573870163`, step size is effectively zero; singularity or stiff system suspected.

I really am not acquainted with Mathematica, so I really don’t how to solve a system of ODEs with boundary conditions in infinite.

Thanks!

How to effectively create "needed" boilerplate?

In the context of a web application

When we send a request from front end to back end we have to map the data eg in post request
{ something : this.something }

Then when we receive it, we have to map it to a .new() method like some_class.new(something = input('something'))

And someone had to make the .new(something): some_class.something = something

Keeping in mind this is multiple languages. So the first thing is say JS, then next is say python or go, and finally a DB wrapper, ORM, etc.

Is this just unavoidable? Is it a best practice to build some kind of string generator that can take a representation in a known format and generate the various above (slightly different) mappings?

How to work effectively with peer team?

We are a Reporting team working of different ETL patterns ultimately building powerbi reports. We just came to know that our team will be having a peer team to collaborate with. Both teams are responsible for different PowerBi reports but will be using the same ETL tech stack. I think it is recipe for disaster having to share the tech stack with other team. My manager thinks that this is going to speed up delivery as two smaller teams will be going faster than one large team. My question here is how to manage things between two teams for such situations? Any tips for me?

design – How do you effectively track the history of changes to a text field in the database on a content editing platform?

Say I have a website/platform that allows people to submit business names in order to build a high quality business name database. You can apply this to any subject or topic, such as building a database of travel destinations, of movie titles, of quotes, etc. One of the main problems is how to guarantee accuracy and quality.

So what I’m thinking of doing is to sort of gamify it like StackOverflow and related sites. Essentially offering badges for contributing. You get some badges for adding content, cleaning up content, verifying content, etc.. But the problem then is how do you prevent people from cheating the system?

For example, say a person uploads a new business name. That’s 1 creation point. But it was spelled wrong, so update business name. That’s 1 update point. Now change it back to original incorrect spelling, 1 more update point. Change it back, another point, etc.. Back and forth and back and forth. Rack up the points.

So the initial question is, how do you prevent this? What I’m thinking about is somehow tracking the changes to a record. If someone notices a person doing this, then they get reported and then lose all their points related to the cheating attempts. Something like that.

But imagine recording the snip/snap/snip/snap of the changes to and from values. 1000 changes to one record, adding and removing random characters. If you had a database table with a “history” table attached to it for changes to a field, it would fill up quickly. So the main question is, how do you effectively do this? How do you keep a small long of changes, and prevent the cheating?

For example, say user A creates a business “Foo Bar”, then user B changes it to “Foo Bar Baz”, then user C changes it back to “Foo Bar”, then user A to “Foo Bar Inc.” (all caps) then finally several users verify it is “Foo Bar Inc.”. Say someone else comes along now after it’s been verified a few times, and they say it’s “Foo Bar” again. We look in the history table and see this option has been tried before and it was marked invalid. That would be efficient in this case.

But what about the random case mentioned before (one user spams the system entering “asdfcda” then “cidajcoid” then “ciadojc” as the business name to rack up points). If the history table grows and grows to 10,000 items long for each of the 100,000 businesses, it’s going to take a while to check every history list for each change. So somehow you need to optimize this. How can this be optimized?

In short, how do you effectively track the history of changes to a text field in the database on a content editing platform?

Has anyone elaborated on the problems and solutions before online somewhere? If not, what are the key points to address in an initial prototype?